Executando testes junit em paralelo em uma build Maven?

Estou usando o JUnit 4.4 e o Maven e tenho um grande número de testes de integração de longa duração.

Quando se trata de paralelizar suítes de testes, existem algumas soluções que permitem que eu execute cada método de teste em uma única class de teste em paralelo. Mas tudo isso exige que eu mude os testes de uma forma ou de outra.

Eu realmente acho que seria uma solução muito mais limpa para executar X classs de teste diferentes em threads X em paralelo. Eu tenho centenas de testes, então eu realmente não me importo com o encadeamento de classs de teste individuais.

Há alguma maneira de fazer isso?

Use o plugin maven:

   org.apache.maven.plugins maven-surefire-plugin 2.7.1  classs 5     

Do junit 4.7 agora é possível executar testes em paralelo sem usar o TestNG. Na verdade, isso tem sido possível desde 4.6, mas há uma série de correções sendo feitas em 4.7, o que a tornará uma opção viável. Você também pode executar testes paralelos com a mola, sobre os quais você pode ler aqui

Inspirado pelo corredor experimental ParallelComputer da JUnit, eu construí meus próprios corredores ParallelSuite e ParallelParameterized . Usando esses corredores, pode-se facilmente paralelizar suítes de testes e testes parametrizados.

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

O uso é simples. Basta alterar o valor das annotations @RunWith para uma dessas classs Parallel * .

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

O tempus-fugit oferece algo semelhante, verifique os documentos para detalhes. Ele se baseia na JUnit 4.7 e você apenas marca seu teste em @RunWith(ConcurrentTestRunner) .

Felicidades

O TestNG pode fazer isso (esse foi o meu primeiro reflexo – depois vi que você já tem muitos testes).

Para o JUnit, veja o paralelo-junit .

Você pode verificar a biblioteca de software livre – Test Load Balancer . Ele faz exatamente o que você pede – execute classs de teste diferentes em paralelo. Isso se integra ao nível ant-junit para que você não precise alterar seus testes de qualquer maneira. Eu sou um dos autores da biblioteca.

Além disso, pense em não executá-los em encadeamentos, pois você pode precisar de uma checkbox de proteção de nível de processo. Por exemplo, se você está atingindo um database em seus testes de integração, não deseja que um teste falhe porque outro teste adicionou alguns dados em um thread diferente. Na maioria das vezes, os testes não são escritos com isso em mente.

Finalmente, como resolveu este problema até agora?

Você pode executar os testes em paralelo usando o ParallelComputer fornecido pela própria Junit. Aqui está um pequeno trecho para você começar.

 Class[] cls = { TestCase1.class, TestCase2.class }; Result result = JUnitCore.runClasses(ParallelComputer.classs(), cls); List failures = result.getFailures(); 

Isso ajudará quando você precisar executar testes a partir do código, pois não possui dependencies no Maven ou em outras ferramentas de gerenciamento de compilation.

Observe que isso executará todos os casos de teste em paralelo. Se você tiver alguma dependência entre diferentes casos de teste, isso poderá resultar em falsos positivos. Você não deve ter testes interdependentes de qualquer maneira.

Você pode alterar seu teste para teste TestNg em um minuto (você só precisa alterar importações), TestNG é o melhor em testes paralelos.

Você poderia tentar Gridgain que permite executar distribuir seus testes em uma grade de computação.