¿Cómo puedo incluir clases de prueba en Maven jar y ejecutarlas?

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 ningún problema acceder a las clases fuente en las clases de prueba, pero me gustaría ejecutar un AllTest.class 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 se puede acceder a clases de prueba desde clases de aplicación? Alternativamente, ¿cómo puede Maven empaquetar un tarro de grasa incluyendo clases de prueba y ejecutar pruebas?

No debe acceder a las clases de prueba desde el código de su aplicación, sino crear una principal (la misma principal) en el scope 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 la 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 el scope de la test )

Lo que básicamente significa un flask gordo con la adición de clases de prueba (y sus dependencias). El Maven Jar Plugin y su objective de test-jar no se adaptan a esta necesidad. El Maven Shade Plugin y su opción shadeTestJar no ayudaron tampoco.

Entonces, ¿cómo crear en Maven un contenedor de grasa con clases de prueba y dependencias externas?

El complemento Maven Assembly es un candidato perfecto en este caso.

Aquí hay una muestra mínima de POM:

  4.0.0 com.sample sample-project 1.0-SNAPSHOT    maven-assembly-plugin 2.3  src/main/assembly/assembly.xml    make-assembly package  single     com.sample.TestMain           junit junit 4.11 test    

La configuración anterior establece la clase principal definida por usted en sus clases de prueba. Pero eso no es suficiente.

También necesita crear un archivo descriptor , en la carpeta src\main\assembly un archivo assembly.xml con el siguiente contenido:

  fat-tests  jar  false   / true true test     ${project.build.directory}/test-classes /  **/*.class  true    

La configuración anterior es:

  • establecer dependencias externas que se tomarán del scope de la test (que también tomará el ámbito de compile )
  • establecer un fileset de fileset para incluir clases de prueba comstackdas como parte del paquete de grasa empaquetado
  • estableciendo un jar final con clasificador de fat-tests (por lo tanto, su archivo final será algo así como sampleproject-1.0-SNAPSHOT-fat-tests.jar ).

A continuación, puede invocar el principal de la siguiente manera (desde la carpeta de target ):

 java -jar sampleproject-1.0-SNAPSHOT-fat-tests.jar 

Desde dicho main, también podría 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 Java simple principal

Ejemplo de suite de prueba:

 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ías 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); } } 

El principal anterior entonces ejecutará el conjunto de pruebas que ejecutará en cadena todas las pruebas configuradas.