Estruturando a Suíte E2E com Kotest e Playwright
Depois de concluirmos esta aula, nós:
- Saberemos configurar os diretórios de código-fonte e recursos dos nossos testes End-to-End.
- Saberemos iniciar nossa aplicação web antes da execução dos nossos testes End-to-End e pará-la após a conclusão dos testes.
- Compreenderemos como podemos executar testes End-to-End que utilizam o Kotest Framework e Playwright.
Esta aula assume que:
- Você está familiarizado com tags e anotações de filtragem no JUnit Platform / Kotest.
- Você sabe executar testes de integração que utilizam o Kotest Framework.
- Você está familiarizado com o Kotest Framework.
- Você sabe criar um build automatizado que executa testes End-to-End isolados dos testes unitários e de integração.
Os Requisitos da Nossa Suíte de Build End-to-End
Os requisitos do nosso build para testes End-to-End são:
- Nossos testes End-to-End devem possuir um diretório de código-fonte separado. O diretório
src/end-to-end-test/kotlin(ousrc/e2eTest/kotlin) deve conter o código-fonte das nossas especificações End-to-End. - Nossos testes End-to-End devem possuir um diretório de recursos separado. O diretório
src/end-to-end-test/resources(ousrc/e2eTest/resources) deve conter os recursos dos nossos testes End-to-End (como scripts SQL e propriedades de ambiente). - Apenas os testes unitários devem ser executados por padrão no ciclo rápido de desenvolvimento.
- Devemos ser capazes de executar apenas os testes unitários, apenas os testes de integração ou apenas os testes End-to-End.
- Nosso ambiente de teste deve iniciar nossa aplicação web antes que nossos testes End-to-End sejam executados e pará-la após a execução dos testes End-to-End.
Vamos começar adicionando um novo diretório de código-fonte ao nosso projeto.
Adicionando um Novo Diretório de Código-Fonte ao Projeto
Quando queremos isolar fisicamente as especificações End-to-End do Kotest das especificações unitárias (src/test/kotlin) e de integração (src/integration-test/kotlin), configuramos três diretórios de teste distintos:
src/test/kotlin: Especificações unitárias rápidas (*Spec.kt).src/integration-test/kotlin: Especificações de integração com Spring e Testcontainers (*Spec.kt).src/end-to-end-test/kotlin: Especificações End-to-End com Kotest e Playwright (*Spec.kt).
Em projetos Maven (para equipes que mantêm builds híbridos ou multi-módulos Maven com Kotlin) ou no Gradle JVM Test Suite Plugin, garantimos que o compilador Kotlin (kotlin-maven-plugin ou jvm-test-suite) reconheça o diretório src/end-to-end-test/kotlin:
|
|
A seguir, adicionaremos o diretório de recursos correspondente.
Adicionando um Novo Diretório de Recursos ao Projeto
Da mesma forma que adicionamos o diretório de código-fonte, precisamos registrar o diretório de recursos src/end-to-end-test/resources para que os scripts SQL e configurações dos testes E2E fiquem disponíveis no classpath durante a fase de verificação:
|
|
Vamos avançar e descobrir como configuramos os perfis de execução para isolar cada nível da pirâmide de testes.
Configurando Perfis de Execução e Categorias (@Tag / @EndToEndTest)
Quando executamos tanto testes de integração quanto testes End-to-End no motor do JUnit Platform (com kotest-runner-junit5), utilizamos anotações de marcação para distinguir o tipo de especificação:
|
|
Para controlar quais especificações são executadas em cada perfil:
Primeiro, definimos uma propriedade skip.failsafe.plugin (por padrão true no perfil dev) para que o build padrão execute apenas os testes unitários rápidos.
Segundo, criamos um perfil dedicado chamado end-to-end-test. Este perfil garante que apenas os testes End-to-End marcados com @EndToEndTest (endToEndTest) sejam executados quando o perfil end-to-end-test estiver ativo:
|
|
Terceiro, configuramos o plugin de verificação (maven-failsafe-plugin no Maven ou a task correspondente no Gradle) para filtrar pelo grupo ${failsafe.junit.category} e incluir todas as classes *Spec:
|
|
Vamos avançar e descobrir como iniciamos e paramos nossa aplicação web para os testes End-to-End.
Iniciando e Parando Nossa Aplicação Web
Antes de podermos executar nossos testes End-to-End com Playwright, temos que iniciar nossa aplicação web antes que os testes End-to-End rodem e pará-la após a conclusão dos testes. Existem duas abordagens arquiteturais para fazer isso:
- Em aplicações Spring Framework tradicionais (sem Spring Boot): Iniciar um container servlet externo (como Jetty ou Tomcat) na fase
pre-integration-teste pará-lo na fasepost-integration-testapenas dentro do perfilend-to-end-test, para não desacelerar os testes de integração. - Em aplicações Spring Boot 4 modernas (Recomendado): Iniciar e parar o servidor web embarcado diretamente através do suporte de testes do Spring Boot (
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)ouDEFINED_PORT) integrado aoSpringExtensiondo Kotest e ao Testcontainers! Falaremos em detalhes sobre essa configuração nas próximas aulas deste tópico.
Executando Nossos Testes End-to-End
Quando executamos a suíte End-to-End (por exemplo, mvn clean verify -P end-to-end-test ou ./gradlew endToEndTest), o fluxo completo ocorre em três etapas claras:
- O servidor da aplicação web (e o banco de dados PostgreSQL via Testcontainers) é iniciado antes da execução das especificações End-to-End.
- O runner do JUnit Platform executa apenas as especificações Kotest que pertencem à categoria
endToEndTest(comoShowMessageTextSpecouTaskEndToEndSpec). - O navegador Playwright e o servidor web são encerrados de forma limpa após a execução de todas as especificações End-to-End.
Vamos resumir o que aprendemos nesta aula.
Resumo
Esta aula nos ensinou três coisas:
- Devemos manter diretórios de código-fonte (
src/end-to-end-test/kotlin) e recursos (src/end-to-end-test/resources) dedicados para as especificações End-to-End. - Se estivermos usando o Spring Boot 4, podemos iniciar e parar nossa aplicação web aproveitando seu suporte nativo de testes (
@SpringBootTest(webEnvironment = ...)). - Podemos isolar a execução de testes unitários, de integração e End-to-End combinando perfis/tasks de build e anotações de categoria (
@EndToEndTest).