Executando testes JUnit em paralelo com o Maven

Executando testes JUnit em paralelo com o Maven

1. Introdução

Embora a execução de testes em série funcione bem na maioria das vezes. Às vezes, podemos precisar acelerar as coisas. Nessas situações, testes paralelos podem ajudar.

JUnit 4.7 and later versions make it possible to execute tests in parallel using Maven’s Surefire Plugin. Em poucas palavras, o Surefire fornece duas maneiras de executar testes em paralelo:

  • A primeira abordagem usa multithreading dentro de um único processo JVM

  • Enquanto a segunda abordagem usa vários processos da JVM

Neste tutorial, vamos cobrir como configurar o Surefire para executar testes JUnit em paralelo dentro de um único processo JVM. Em seguida, veremos como executar testes em paralelo dentro de um projeto multimodule Maven.

2. Dependências do Maven

Vamos começar importando as dependências necessárias. We’ll need to use JUnit 4.7 or later along with Surefire 2.16 or later:


    junit
    junit
    4.12
    test

    org.apache.maven.plugins
    maven-surefire-plugin
    2.22.0

3. Executando testes paralelos

Para executar um teste em paralelo, devemos usar um executor de teste que estendeorg.junit.runners.ParentRunner.

No entanto, mesmo os testes que não declaram um executor de teste explícito funcionam, já que o executor padrão estende esta classe.

A seguir, para demonstrar a execução de testes paralelos, usaremos um conjunto de testes com duas classes de teste, cada uma com alguns métodos. De fato, qualquer implementação padrão de um conjunto de testes JUnit serviria.

3.1. Usando Parâmetro Paralelo

Primeiro, vamos habilitar o comportamento paralelo no Surefire usando o sparameterparallel . It states the level of granularity at which we would like to apply parallelism.

Os valores possíveis são:

  • methods – executa métodos de teste em threads separados

  • classes – executa classes de teste em threads separados

  • classesAndMethods – executa classes e métodos em threads separados

  • suites – runs suites em paralelo

  • suitesAndClasses – runs suites e classes em threads separados

  • suitesAndMethods – grita threads separados para classes e métodos

  • all – executa suites, classes, bem como métodos em threads separados

Em nosso exemplo, usamosall:


    all

Em segundo lugar, vamos definir o número total de threads que queremos que o Surefire crie. Podemos fazer isso de duas maneiras:

UsandothreadCount, que define o número máximo de threads que o Surefire criará:

10

Ou usando o parâmetrouseUnlimitedThreads onde um thread é criado por núcleo de CPU:

true

Por padrão,threadCount é por núcleo de CPU. Podemos usar o parâmetroperCoreThreadCount para habilitar ou desabilitar este comportamento:

true

3.2. Usando limitações de contagem de threads

Agora, digamos que queremos definir o número de threads a serem criados no método, classe e nível de suíte. We can do this with the threadCountMethods, threadCountClasses and threadCountSuites parameters.

Vamos combinar esses parâmetros comthreadCount da configuração anterior: _ _

2
2
6

Como usamosall emparallel, , swe definiu as contagens de encadeamentos para métodos, suítes e também classes. No entanto, não é obrigatório definir o parâmetro folha. O Surefire deduz o número de encadeamentos a serem usados, caso os parâmetros folha sejam omitidos.

Por exemplo, sethreadCountMethods for omitido, só precisamos ter certeza de quethreadCount>threadCountClasses  +threadCountSuites.

Às vezes, podemos querer limitar o número de threads criados para classes, conjuntos ou métodos, mesmo enquanto estivermos usando um número ilimitado de threads.

Também podemos aplicar limitações de contagem de threads nesses casos:

true
2

3.3. Definindo tempos limite

Às vezes, podemos precisar garantir que a execução do teste tenha um prazo.

To do that we can use the parallelTestTimeoutForcedInSeconds parameter. Isso interromperá os threads em execução no momento e não executará nenhum dos threads em fila após o tempo limite expirar:

5

Outra opção é usarparallelTestTimeoutInSeconds.

Nesse caso, apenas os threads em fila serão impedidos de executar:

3.5

No entanto, com as duas opções, os testes terminarão com uma mensagem de erro quando o tempo limite terminar.

3.4. Ressalvas

O Surefire chama métodos estáticos anotados com@Parameters,@BeforeClass e@AfterClass no encadeamento pai. Portanto, verifique possíveis inconsistências de memória ou condições de corrida antes de executar testes em paralelo.

Além disso, testes que modificam o estado compartilhado definitivamente não são bons candidatos para execução em paralelo.

4. Execução de teste em projetos Maven com vários módulos

Até agora, nos concentramos em executar testes em paralelo dentro de um módulo Maven.

Mas digamos que temos vários módulos em um projeto Maven. Como esses módulos são construídos seqüencialmente, os testes para cada módulo também são executados seqüencialmente.

We can change this default behavior by using Maven’s -T parameter which builds modules in parallel. Isso pode ser feito de duas maneiras.

Podemos especificar o número exato de threads a serem usados ​​durante a criação do projeto:

mvn -T 4 surefire:test

Ou use a versão portátil e especifique o número de threads a serem criados por núcleo de CPU:

mvn -T 1C surefire:test

De qualquer maneira, podemos acelerar os testes e criar tempos de execução.

5. Conclusão

Para resumir, começamos habilitando o comportamento multi-threaded e definindo o grau de paralelismo usando o parâmetroparallel. Posteriormente, aplicamos limitações no número de threads que o Surefire deve criar. Posteriormente, definimos parâmetros de tempo limite para controlar os tempos de execução do teste.

Finalmente, vimos como podemos reduzir o tempo de execução da compilação e, portanto, testar o tempo de execução em projetos Maven com vários módulos.

Como sempre, o código apresentado aqui éavailable on GitHub.