2009-01-08 32 views
98

estoy usando JUnit 4.4 y Maven y tengo un gran número de pruebas de integración de larga duración.Ejecutando pruebas junit en paralelo en una compilación Maven?

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 diferentes clases de prueba 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?

Respuesta

36

A partir del 4 de junio, ahora es posible ejecutar pruebas en paralelo sin utilizar 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 sobre here

+1

La página enlazada dice que "para la mayoría de las soluciones de doble núcleo, correr con hilos paralelos nunca es más rápido que ejecutar sin hilos". ¿Sigue siendo el caso? – Raedwald

+2

Creo que si sus pruebas hacen IO, aún así se beneficiarían. Por ejemplo, si las pruebas de su unidad se parecen más a las pruebas de integración y llegan a la base de datos, ejecutarlas en paralelo debería acelerarlas. – Dave

+0

@Raedwald No esperes demasiado * demasiado para las pruebas cortas de unidades no vinculadas es lo que trato de decir. Las versiones más recientes de infalible también son mejores/más eficientes que las 2.5 descritas en la publicación, por lo que puede obtener resultados ligeramente mejores. – krosenvold

4

TestNG can do that (este fue mi primer reflejo, entonces vi que ya estás teniendo muchos testcases).

Para JUnit, mira parallel-junit.

+3

Lamentablemente esta no es la respuesta a la pregunta que estoy formulando. parallel-junit solo se ejecuta dentro de una única clase de prueba. TestNG también solo se ejecuta dentro de una sola clase, y mis pruebas no son TestNG. – krosenvold

+0

@PlatinumAzure: Actualicé el enlace. No sé cómo se mantiene este proyecto. Hace poco se hizo otra pregunta para [distribuir la ejecución de pruebas junit en varias máquinas] (http://stackoverflow.com/questions/10690587/running-parallel-junit-tests-on-multiple-remote-machines). – philant

-2

Puede cambiar su prueba para que sea TestNg en un minuto (solo necesita cambiar las importaciones), TestNG es la mejor prueba en paralelo.

-2

Puede intentar Gridgain que le permite ejecutar distribuir sus pruebas a través de una cuadrícula de cálculo.

+1

He probado la solución GridGain y he tenido dos problemas importantes. En primer lugar, debe decirle a GridGain que excluya del classpath de la tarea de grid todo lo que GridGain también utilice, p. Primavera y muchas cosas de Apache Commons. En segundo lugar, la carga de clases de la red, aunque es una idea brillante, no funciona para las bibliotecas que desean buscar el classpath, p. Spring –

5

tempus-fugit ofrece algo similar, consulte los documentos para obtener más información. Se basa en JUnit 4.7 y usted simplemente marca su prueba en @RunWith(ConcurrentTestRunner).

Saludos

3

Se puede extraer de 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 puede necesitar un entorno limitado 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.

Por último, ¿cómo han resuelto este problema hasta ahora?

62

Uso experto plugin:

<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> 
+9

es compatible con surefire si usa Junit 4.7 o posterior. [infalible guía] (http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html) – jontejj

9

Inspirado por experimental corredor ParallelComputer de JUnit que he construido mi propio ParallelSuite y ParallelParameterized corredores. 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 valor de anotaciones a una de estas Paralela * clases.

@RunWith(ParallelSuite.class) 
@SuiteClasses({ATest.class, BTest.class, CTest.class}) 
public class ABCSuite {} 
+0

SuiteClasses anotación acepta cadenas – gstackoverflow

2

Puede ejecutar las pruebas en paralelo utilizando ParallelComputer proporcionado por el propio 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 le ayudará cuando usted necesita para ejecutar las pruebas de código ya que no tiene dependencias de Maven o cualquier otra herramienta de gestión de construcción.

Tenga en cuenta que esto ejecutará todos los casos de prueba en paralelo, si tiene alguna dependencia entre diferentes casos de prueba, podría dar lugar a falsos positivos. NO DEBE tener pruebas interdependientes de todos modos.

Cuestiones relacionadas