Execução de teste simultânea na primavera 5

Execução de teste simultânea na primavera 5

1. Introdução

Começando comJUnit 4, os testes podem ser executados em paralelo para ganhar velocidade para suítes maiores. O problema era que a execução de teste simultânea não era totalmente suportada porSpring TestContext Framework antes deSpring 5.

Neste artigo rápido, mostraremos comouse Spring 5 to run our tests in Spring projects concurrently.

2. Configuração do Maven

Como um lembrete, para executar testes deJUnit em paralelo, precisamos configurar omaven-surefire-plugin para habilitar o recurso:


    
        org.apache.maven.plugins
        maven-surefire-plugin
        2.19.1
        
            methods
            true
        
    

Você pode verificar oreference documentation para uma configuração mais detalhada na execução de teste paralelo.

3. Teste Simultâneo

O teste de exemplo a seguir falharia ao executar em paralelo para versões anteriores aSpring 5.

No entanto, ele será executado sem problemas emSpring 5:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Spring5JUnit4ConcurrentTest.SimpleConfiguration.class)
public class Spring5JUnit4ConcurrentTest implements ApplicationContextAware, InitializingBean {

    @Configuration
    public static class SimpleConfiguration {}

    private ApplicationContext applicationContext;

    private boolean beanInitialized = false;

    @Override
    public void afterPropertiesSet() throws Exception {
        this.beanInitialized = true;
    }

    @Override
    public void setApplicationContext(
      final ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Test
    public void whenTestStarted_thenContextSet() throws Exception {
        TimeUnit.SECONDS.sleep(2);

        assertNotNull(
          "The application context should have been set due to ApplicationContextAware semantics.",
          this.applicationContext);
    }

    @Test
    public void whenTestStarted_thenBeanInitialized() throws Exception {
        TimeUnit.SECONDS.sleep(2);

        assertTrue(
          "This test bean should have been initialized due to InitializingBean semantics.",
          this.beanInitialized);
    }
}

Ao executar sequencialmente, os testes acima levariam cerca de 6 segundos para serem aprovados. Com a execução simultânea, levará apenas cerca de 4,5 segundos - o que é bastante típico por quanto tempo também podemos economizar em suítes maiores.

4. Sob o capô

O principal motivo pelo qual as versões anteriores da estrutura não suportavam a execução de testes simultaneamente era devido ao gerenciamento deTestContext porTestContextManager.

EmSpring 5, oTestContextManager usa uma thread local -TestContext - para garantir que as operações emTestContexts em cada thread não interfiram umas com as outras. Assim, a segurança do encadeamento é garantida para a maioria dos testes simultâneos no nível do método e no nível da classe:

public class TestContextManager {

    // ...
    private final TestContext testContext;

    private final ThreadLocal testContextHolder = new ThreadLocal() {
        protected TestContext initialValue() {
            return copyTestContext(TestContextManager.this.testContext);
        }
    };

    public final TestContext getTestContext() {
        return this.testContextHolder.get();
    }

    // ...
}

Observe que o suporte à simultaneidade não se aplica a todos os tipos de testes; we need to exclude tests that:

  • alterar estados compartilhados externos, como estados em caches, bancos de dados, filas de mensagens etc.

  • requerem ordens de execução específicas, por exemplo, testes que usamJUnit's@FixMethodOrder

  • modifique osApplicationContext, que geralmente são marcados por@DirtiesContext

5. Sumário

Neste tutorial rápido, mostramos um exemplo básico usandoSpring 5 para executar testes em paralelo.

Como sempre, o código de exemplo pode ser encontradoover on Github.