java - tutorial - Ejecutar pruebas junit en paralelo en una compilación Maven?
pruebas unitarias de software ejemplo (9)
Desde el punto 4.7, ahora es posible ejecutar pruebas en paralelo sin usar TestNG. En realidad, ha sido posible desde 4.6, pero hay una serie de correcciones en 4.7 que lo harán una opción viable. También puede ejecutar pruebas paralelas con la primavera, que puede leer here
Estoy usando JUnit 4.4 y Maven y tengo una gran cantidad de pruebas de integración de larga ejecución.
Cuando se trata de paralelizar suites de prueba, hay algunas soluciones que me permiten ejecutar cada método de prueba en una sola clase de prueba en paralelo. Pero todos estos requieren que cambie las pruebas de una manera u otra.
Realmente creo que sería una solución mucho más limpia ejecutar X clases de prueba diferentes en subprocesos X en paralelo. Tengo cientos de pruebas, así que realmente no me importa enhebrar clases de prueba individuales.
¿Hay alguna manera de hacer esto?
Inspirado por el corredor experimental de ParallelComputer JUnit, he construido mis propios corredores ParallelSuite y ParallelParameterized . Usando estos corredores, uno puede paralelizar fácilmente suites de prueba y pruebas parametrizadas.
ParallelSuite.java
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(4);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
ParallelParameterized.java
public class ParallelParameterized extends Parameterized {
public ParallelParameterized(Class<?> arg0) throws Throwable {
super(arg0);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(8);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
El uso es simple. Simplemente cambie @RunWith el valor de las anotaciones a una de estas clases de Parallel * .
@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}
Puede consultar la biblioteca de código abierto - Test Load Balancer . Hace exactamente lo que pide: ejecutar diferentes clases de prueba en paralelo. Esto se integra en el nivel junit para que no tenga que cambiar sus pruebas de todos modos. Soy uno de los autores de la biblioteca.
Además, piense en no ejecutarlos en subprocesos ya que es posible que necesite un entorno limitado a nivel de proceso. Por ejemplo, si está presionando un DB en sus pruebas de integración, no quiere que falle una prueba porque otra prueba agregó algunos datos en una secuencia diferente. La mayoría de las veces, las pruebas no se escriben con esto en mente.
Finalmente, ¿cómo se ha resuelto este problema hasta ahora?
Puede ejecutar las pruebas en paralelo utilizando ParallelComputer proporcionado por Junit. Aquí hay un pequeño fragmento para que comiences.
Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();
Esto ayudará cuando necesite ejecutar pruebas del código, ya que no tiene dependencias en Maven ni en ninguna otra herramienta de administración de compilación.
Tenga en cuenta que esto ejecutará todos los casos de prueba en paralelo; si tiene dependencias entre diferentes casos de prueba, podría dar como resultado falsos positivos. NO DEBE tener pruebas interdependientes de todos modos.
Puede probar Gridgain que le permite ejecutar distribuya sus pruebas a través de una grilla de cálculo.
Puedes cambiar tu prueba para que sea TestNg en un minuto (solo necesitas cambiar las importaciones), TestNG es lo mejor en pruebas paralelas.
Use el plugin maven:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.1</version>
<configuration>
<parallel>classes</parallel>
<threadCount>5</threadCount>
</configuration>
</plugin>
</plugins>
</build>
tempus-fugit ofrece algo similar, revisa los documentos para más detalles. Se basa en JUnit 4.7 y usted simplemente marca su prueba en @RunWith(ConcurrentTestRunner)
.
Aclamaciones
TestNG puede hacer eso (este fue mi primer reflejo, entonces vi que ya tienes muchos testcase).
Para JUnit, mira parallel-junit .