Isolando Testes Unitários e de Integração no Build
Ao concluirmos esta aula, nós:
- Seremos capazes de adicionar diretórios customizados de código-fonte (
src/integration-test/kotlin) e recursos (src/integration-test/resources) no nosso build Maven. - Saberemos como executar nossos testes de integração separadamente dos testes unitários usando o Maven Failsafe Plugin e tags do JUnit Jupiter 6 (
@Tag). - Compreenderemos como pular (skip) testes unitários ou testes de integração utilizando perfis do Maven (Maven profiles).
Os Requisitos do Nosso Build
Os requisitos do nosso processo de build para testes de integração são:
- Nossos testes de integração devem ter um diretório de código-fonte separado: o diretório src/integration-test/kotlin (ou src/integration-test/java) deve conter o código-fonte dos nossos testes de integração.
- Nossos testes de integração devem ter um diretório de recursos separado: o diretório src/integration-test/resources deve conter os arquivos de configuração e scripts SQL dos nossos testes de integração.
- Apenas os testes unitários devem ser executados por padrão no ciclo de desenvolvimento rápido.
- Devemos ser capazes de executar apenas os testes de integração quando desejarmos.
- Os nomes das nossas classes de teste de integração não precisam obrigatoriamente terminar ou começar com um sufixo especial (como
*IT.kt), pois usamos tags semânticas do JUnit 6 (@Tag("integrationTest")).
Vamos começar criando os perfis do Maven (Maven profiles) que controlam quando os testes unitários e os testes de integração são executados.
Criando Perfis Maven para Testes Unitários e de Integração
Precisamos criar dois perfis no nosso arquivo pom.xml:
- O perfil dev é o perfil padrão do nosso build e garante que apenas os testes unitários sejam executados quando o perfil dev estiver ativo.
- O perfil integration-test garante que apenas os testes de integração sejam executados quando o perfil integration-test for utilizado.
Podemos criar esses perfis seguindo dois passos:
Primeiro, adicionamos duas propriedades na seção <properties> do nosso arquivo pom.xml:
- A propriedade
skip.unit.testsétruequando o Maven deve pular os nossos testes unitários. Como queremos que os testes unitários rodem por padrão, seu valor inicial deve serfalse. - A propriedade
skip.integration.testsétruequando o Maven deve pular os nossos testes de integração. Seu valor inicial padrão deve sertrue.
Após adicionarmos essas propriedades ao nosso pom.xml, a seção properties fica assim:
|
|
Segundo, criamos os perfis necessários seguindo estes passos:
- Criamos um perfil chamado
deve garantimos que ele esteja ativo por padrão (<activeByDefault>true</activeByDefault>). - Criamos um perfil chamado
integration-testque inverte as propriedades (skip.integration.tests = falseeskip.unit.tests = true), garantindo que o Maven execute apenas os testes de integração quando este perfil estiver ativo.
Após adicionarmos esses perfis ao nosso build Maven, o arquivo pom.xml terá a seguinte configuração de <profiles>:
|
|
Nosso próximo passo é configurar os diretórios de código-fonte e recursos dos nossos testes de integração.
Adicionando Diretórios de Código-Fonte e Recursos ao Build Maven
Podemos adicionar diretórios extras de código-fonte (src/integration-test/kotlin) e recursos (src/integration-test/resources) no Maven utilizando o Build Helper Maven Plugin (org.codehaus.mojo:build-helper-maven-plugin). Antes de configurá-lo, declaramos o plugin na seção <plugins> do nosso pom.xml:
|
|
Agora podemos registrar os diretórios de código e recursos seguindo três passos:
Primeiro, adicionamos a seção <executions> na declaração do Build Helper Maven Plugin:
|
|
Segundo, criamos uma execução (<execution>) que adiciona o diretório de código-fonte dos nossos testes de integração (src/integration-test/kotlin) ao build. Esta execução invoca o goal add-test-source durante a fase generate-test-sources do ciclo de vida padrão do Maven:
|
|
Terceiro, criamos uma execução que adiciona o diretório de recursos dos nossos testes de integração (src/integration-test/resources) ao build. Esta execução invoca o goal add-test-resource na fase generate-test-resources do ciclo de vida do Maven:
|
|
A seguir, precisamos garantir que os nossos testes unitários sejam executados apenas quando o perfil dev estiver ativo.
Configurando o Maven para Pular Testes Unitários Quando Necessário
O Maven Surefire Plugin não executa testes unitários quando a sua opção de configuração skipTests é true. Como queremos executar nossos testes unitários apenas quando o perfil dev estiver ativo, configuramos o Surefire para ler o valor dessa opção a partir da propriedade ${skip.unit.tests}:
|
|
Antes de configurarmos o Maven para rodar nossos testes de integração, vamos escrever um teste de integração simples com JUnit Jupiter 6.
Escrevendo um Teste de Integração Simples
No antigo JUnit 4, usávamos a anotação experimental @Category(IntegrationTest::class) com uma interface marcadora vazia. No JUnit Jupiter 6, o suporte a categorização é nativo de primeira classe através da anotação @Tag (que inclusive pode ser combinada em uma meta-anotação @IntegrationTest em Kotlin)!
Veja como podemos criar uma meta-anotação @IntegrationTest limpa e reutilizável:
|
|
E a nossa classe SampleIntegrationTest anotada com @IntegrationTest (ou diretamente com @Tag("integrationTest")):
|
|
Vamos agora configurar o Maven para executar os nossos testes de integração!
Executando Testes de Integração com o Maven Failsafe Plugin
Para executar testes de integração no ciclo de vida do Maven, utilizamos o Maven Failsafe Plugin (maven-failsafe-plugin). Nosso primeiro passo é declarar o plugin na seção <plugins> do pom.xml:
|
|
Agora configuramos o Maven Failsafe Plugin seguindo quatro passos:
Primeiro, garantimos que ambos os goals integration-test e verify sejam executados. O goal integration-test executa os testes de integração e o goal verify analisa os relatórios gerados e falha o build caso algum teste de integração tenha falhado:
|
|
Segundo, configuramos o Failsafe para escanear todas as classes de teste compiladas (independentemente do sufixo do arquivo):
|
|
Terceiro, configuramos o Failsafe para executar apenas os testes marcados com a tag integrationTest do JUnit Jupiter 6 através da opção <groups>:
|
|
Quarto, garantimos que o Maven Failsafe Plugin execute os testes de integração apenas quando o perfil integration-test estiver ativo, vinculando <skipTests> à propriedade ${skip.integration.tests}:
|
|
Executando Nossos Testes Unitários e de Integração
Podemos executar apenas os nossos testes unitários rodando o seguinte comando no terminal:
|
|
Ao executarmos esse comando, vemos que apenas os testes unitários são executados:
|
|
E podemos executar apenas os nossos testes de integração rodando o comando:
|
|
Ao executarmos esse comando no terminal, vemos que os testes unitários do Surefire são pulados e apenas os testes de integração do Failsafe são executados:
|
|
Resumo
Esta aula nos ensinou três coisas fundamentais:
- Podemos adicionar diretórios customizados de código-fonte e recursos ao nosso build Maven utilizando o Build Helper Maven Plugin.
- Podemos executar nossos testes de integração de forma isolada utilizando o Maven Failsafe Plugin filtrado por
<groups>integrationTest</groups>(@Tag("integrationTest")do JUnit Jupiter 6). - Podemos pular testes unitários ou testes de integração configurando a opção
skipTestsdos plugins Surefire e Failsafe através de propriedades ativadas por perfis do Maven.