java - que - ¿Cómo puedo incluir clases de prueba en el jar Maven y ejecutarlas?
arquillian tutorial (1)
No debe acceder a las clases de prueba desde el código de su aplicación, sino crear un main (el mismo main) en el alcance de la prueba y crear un artefacto adicional para su proyecto.
Sin embargo, en este artefacto adicional (jar) necesitaría tener:
- Las clases de prueba
- Las clases de código de aplicación
-
Dependencias externas requeridas por el código de la aplicación (en el ámbito de
compile) -
Dependencias externas requeridas por el código de prueba (en alcance de
test)
Lo que básicamente significa un tarro gordo con la adición de clases de prueba (y sus dependencias).
El
plugin Maven Jar
y su objetivo de
test-jar
no satisfarían esta necesidad.
El
complemento Maven Shade
y su opción
shadeTestJar
tampoco ayudarían.
Entonces, ¿cómo crear en Maven un tarro gordo con clases de prueba y dependencias externas?
El complemento de ensamblaje Maven es un candidato perfecto en este caso.
Aquí hay una muestra mínima de POM:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-project</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.sample.TestMain</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
La configuración anterior establece la clase principal definida por usted en sus clases de prueba. Pero eso no es suficiente.
También debe crear un
archivo descriptor
, en la carpeta
src/main/assembly
un archivo
assembly.xml
con el siguiente contenido:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>fat-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
La configuración anterior es:
-
establecer dependencias externas que se tomarán del alcance de
test(que también tomará el alcance decompile) -
establecer un
filesetdefilesetpara incluir clases de prueba compiladas como parte del tarro gordo empaquetado -
establecer un jar final con el clasificador
fat-tests(por lo tanto, su archivo final será algo así comosampleproject-1.0-SNAPSHOT-fat-tests.jar).
Luego puede invocar el main de la siguiente manera (desde la carpeta de
target
):
java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar
Desde este principio, también puede invocar todos sus casos de prueba de la siguiente manera:
- Crear un conjunto de pruebas JUni
- Agregue al conjunto de pruebas las pruebas correspondientes
- Invoque el conjunto de pruebas desde su principal Java simple
Ejemplo de conjunto de pruebas:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({ AppTest.class })
public class AllTests {
}
Nota: en este caso, el conjunto de pruebas solo se refiere a la prueba de muestra
AppTest
.
Entonces podría tener una clase principal de la siguiente manera:
import org.junit.internal.TextListener;
import org.junit.runner.JUnitCore;
public class MainAppTest {
public static void main(String[] args) {
System.out.println("Running tests!");
JUnitCore engine = new JUnitCore();
engine.addListener(new TextListener(System.out)); // required to print reports
engine.run(AllTests.class);
}
}
Lo principal anterior ejecutaría el conjunto de pruebas que ejecutará en cadena todas las pruebas configuradas.
En un proyecto de Maven, tengo clases de prueba y clases de origen en el mismo paquete, pero en diferentes ubicaciones físicas.
.../src/main/java/package/** <-- application code
.../src/test/java/package/** <-- test code
No es un problema acceder a las clases de origen en las clases de prueba, pero me gustaría ejecutar un corredor de prueba en el método principal y acceder a
AllTest.class
para poder crear jar y ejecutar mis pruebas.
public static void main(String[] args) {
// AllTest not found
Result result = JUnitCore.runClasses(AllTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
Pero no funciona ya que no tengo acceso al código de prueba. No entiendo ya que están en el mismo paquete.
Pregunta : ¿cómo pueden acceder las clases de prueba desde las clases de aplicación? Alternativamente, ¿cómo puede Maven empaquetar un tarro gordo que incluye clases de prueba y ejecutar pruebas?