Executando Testes Unitários com Gradle 9 e JUnit 6
Ao concluirmos esta aula, nós:
- Saberemos como configurar e executar testes unitários com o Gradle 9 (Kotlin DSL).
- Compreenderemos por que devemos categorizar nossos testes utilizando Tags do JUnit 6 (
@Tag) (substituindo as antigas@Categorydo JUnit 4). - Seremos capazes de configurar a task
testdo Gradle usandouseJUnitPlatform { includeTags(...) }para rodar apenas os testes unitários da categoria selecionada.
Executando Testes Unitários com o Gradle
Quando criamos um projeto Kotlin/JVM ou Java com o Gradle 9, aplicamos o plugin kotlin("jvm") (ou o plugin java) e configuramos a task de testes para utilizar a plataforma do JUnit 6 (useJUnitPlatform()). Fazemos isso adicionando o seguinte trecho ao nosso arquivo build.gradle.kts:
|
|
[!NOTE] No Gradle legado (Groovy DSL com JUnit 4), aplicava-se
apply plugin: 'java'e o JUnit 4 era o runner padrão. A partir do JUnit 5 e no JUnit 6, a chamadauseJUnitPlatform()na taskTesté obrigatória para ativar o motor JUnit Platform / Jupiter!
Quando utilizamos a configuração padrão, o Gradle executa todos os testes encontrados nas classes compiladas a partir do diretório src/test/kotlin (e src/test/java). Como estamos utilizando o JUnit Jupiter 6, o motor de descoberta identifica automaticamente qualquer classe que contenha pelo menos um método anotado com @Test, @ParameterizedTest, @RepeatedTest ou @TestFactory (ou classes internas anotadas com @Nested).
[!TIP] Se os nossos testes unitários possuírem recursos estáticos — como arquivos de propriedades, JSONs de payload ou arquivos de configuração de log (
logback-test.xml) —, devemos colocá-los no diretóriosrc/test/resources.
Vamos escrever um teste unitário simples que escreve a string "The default configuration" no System.out (println). Após escrevermos esse teste, o código-fonte da nossa classe DefaultTest fica assim:
|
|
Agora podemos executar nossos testes unitários rodando o seguinte comando no terminal:
|
|
[!NOTE] Se não quisermos limpar (
clean) os artefatos compilados antes de executar nossos testes unitários (aproveitando o cache incremental do Gradle 9!), basta usar o comando:
1./gradlew test
Quando executamos nossos testes unitários (com a exibição de standard output habilitada no testLogging), vemos que o Gradle executa nosso teste:
|
|
[!TIP] Por que o Gradle não imprime o
println/System.outpor padrão? Por padrão, o Gradle oculta no console o que é escrito emSystem.outouSystem.errdurante testes que passam. Podemos habilitar essa impressão facilmente adicionandotestLogging { showStandardStreams = true }dentro do blocotasks.withType<Test>()no nossobuild.gradle.kts!
Se escrevermos apenas testes unitários, não precisamos fazer mais alterações no script de build. Porém, na maioria dos projetos, também escreveremos testes de integração e testes End-to-End. Vamos descobrir como usar categorias/tags do JUnit com o Gradle!
Configurando a Categoria (@Tag) dos Nossos Testes Unitários no Gradle
Embora o Gradle permita separar testes unitários, testes de integração e testes End-to-End utilizando conjuntos de código-fonte distintos (SourceSets / JVM Test Suites, como veremos no Capítulo 02), usar Tags do JUnit 6 (@Tag) (que substituíram as @Category do JUnit 4) com o Gradle ainda é extremamente útil!
Por quê? Porque as Tags do JUnit nos dão a possibilidade de criar subcategorias dentro de uma mesma suíte e marcar classes ou métodos individuais — por exemplo, separando testes rápidos que rodam localmente na máquina do desenvolvedor de testes lentos que devem rodar apenas no servidor de CI.
Vamos começar criando a classe CategoryTest que contém um método de teste que escreve "The category: UnitTest" no System.out e é anotada com @Tag("unitTest") (no JUnit 4 usávamos @Category(UnitTest::class) com uma interface marcadora interface UnitTest {}):
|
|
Depois de criarmos nossa classe de teste e configurarmos sua categoria/tag, precisamos instruir o Gradle a executar na task test apenas os testes que pertencem à tag unitTest. Fazemos isso na configuração da task test seguindo estes dois passos:
- Habilitamos o suporte ao JUnit Platform invocando
useJUnitPlatform { ... }(no JUnit 4 antigo usava-seuseJUnit { includeCategories '...' }). - Passamos o nome da tag (
"unitTest") para o métodoincludeTags("unitTest")dentro do blocouseJUnitPlatform.
Adicionamos as seguintes linhas ao nosso arquivo build.gradle.kts:
|
|
Quando executamos ./gradlew clean test agora, observamos que o Gradle executa apenas o teste encontrado na classe CategoryTest e ignora o teste da classe DefaultTest:
|
|
Vamos resumir o que aprendemos nesta aula!
Resumo
Nesta aula, aprendemos quatro pontos essenciais:
- Executamos nossos testes unitários no Gradle aplicando o plugin
kotlin("jvm")(oujava) e habilitandouseJUnitPlatform(). - O Gradle consegue diferenciar testes unitários, de integração e End-to-End tanto via Test Suites / SourceSets quanto via Tags.
- Usar
@Tagdo JUnit 6 (o sucessor de@Categorydo JUnit 4) oferece configuração flexível em nível de classe ou método, permitindo separar testes rápidos locais de testes lentos de CI. - Especificamos a tag/categoria utilizada no Gradle 9 através da opção
includeTags("unitTest")dentro do blocouseJUnitPlatform(que substituiu o antigoincludeCategoriesdo JUnit 4).