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.