05. Introdução aos Testes End-to-End

Ao concluirmos todas as aulas deste tópico, nós:

  • Compreenderemos por que testes End-to-End devem ser isolados em uma suíte separada dos testes unitários e de integração.
  • Saberemos como configurar e executar testes End-to-End no Gradle 9 com jvm-test-suite.
  • Conheceremos a arquitetura do Playwright para JVM e como ele supera a fragilidade do antigo Selenium WebDriver.

Como Configurar o Ambiente para Testes End-to-End com Playwright na JVM

Nesta seção prática, você aprenderá o passo a passo completo, padronizado e repetível para preparar seu projeto Spring Boot com Kotlin e Gradle 9 para a execução de testes End-to-End (E2E) modernos utilizando o Microsoft Playwright para JVM.


1. Por Que Isolar a Suíte E2E no Build?

Testes de ponta a ponta (E2E) navegam por interfaces gráficas reais, realizam requisições de rede completas e dependem de binários de navegadores (como Chromium ou Firefox). Comparados aos testes unitários e de integração, eles possuem características operacionais distintas:

  • Tempo de Execução: Um teste unitário roda em milissegundos; um teste E2E pode levar segundos para carregar páginas, renderizar SPAs e executar scripts no navegador.
  • Dependências Pesadas: A biblioteca de automação do browser e suas ferramentas auxiliares não devem contaminar o classpath da aplicação de produção nem a execução rápida dos testes unitários.
  • Falha Precoce (Fail-Fast): Em pipelines de CI/CD, queremos que erros de lógica quebrem os testes unitários (test) primeiro, antes de despender recursos computacionais subindo navegadores.

Por essas razões, criamos uma suíte dedicada chamada e2eTest via plugin oficial jvm-test-suite do Gradle.


2. Configuração no build.gradle.kts com jvm-test-suite

No Gradle 9 com Kotlin DSL, o plugin nativo jvm-test-suite substitui plugins legados de terceiros, criando automaticamente:

  1. O source set isolado em src/e2eTest/kotlin e src/e2eTest/resources.
  2. As configurações de dependência dedicadas: e2eTestImplementation e e2eTestRuntimeOnly.
  3. A task executável e2eTest e o diretório de relatórios HTML independente em build/reports/tests/e2eTest/.

Abra seu arquivo build.gradle.kts e adicione a suíte e2eTest dentro do bloco testing:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
plugins {
    kotlin("jvm") version "2.4.21"
    kotlin("plugin.spring") version "2.4.21"
    id("org.springframework.boot") version "4.1.2"
    id("io.spring.dependency-management") version "1.1.7"
    `jvm-test-suite`
}

testing {
    suites {
        // Suíte de testes unitários padrão
        val test by getting(JvmTestSuite::class) {
            useJUnitJupiter("6.0.3")
        }

        // Registro da suíte dedicada para testes End-to-End
        val e2eTest by registering(JvmTestSuite::class) {
            useJUnitJupiter("6.0.3")

            dependencies {
                // Permite que os testes E2E acessem as classes e configurações da aplicação
                implementation(project())

                // Microsoft Playwright para JVM (versão 1.50+)
                implementation("com.microsoft.playwright:playwright:1.51.0")

                // Spring Boot Test e asserções fluentes
                implementation("org.springframework.boot:spring-boot-starter-test")
                implementation("org.assertj:assertj-core:3.27.7")
            }

            targets {
                all {
                    testTask.configure {
                        description = "Executa os testes End-to-End com Playwright na JVM."
                        group = "verification"

                        // Garante que os testes unitários rodem antes dos testes E2E
                        shouldRunAfter(test)

                        // Logs detalhados no console durante a execução
                        testLogging {
                            events("passed", "skipped", "failed")
                            showStandardStreams = true
                        }
                    }
                }
            }
        }
    }
}

// Vincula a suíte e2eTest ao ciclo de verificação principal do Gradle
tasks.named("check") {
    dependsOn(testing.suites.named("e2eTest"))
}

[!NOTE] Ao registrar val e2eTest by registering(JvmTestSuite::class), o Gradle configura automaticamente a convenção de diretórios:

  • src/e2eTest/kotlin: Diretório de código-fonte dos testes E2E.
  • src/e2eTest/resources: Diretório de configurações específicas (como application-e2e.properties).

3. Instalação dos Navegadores do Playwright

Diferente do Selenium WebDriver tradicional — que exigia gerenciar drivers externos como o chromedriver instalados no sistema —, o Playwright gerencia versões herméticas e fixas dos navegadores no diretório de cache local (~/.cache/ms-playwright no Linux/macOS ou %USERPROFILE%\AppData\Local\ms-playwright no Windows).

Para automatizar a instalação dos binários necessários (com foco no Chromium), registre uma task JavaExec dedicada no build.gradle.kts:

1
2
3
4
5
6
7
8
// Task para provisionamento automatizado dos binários de navegador do Playwright
tasks.register<JavaExec>("installPlaywrightBrowsers") {
    group = "verification"
    description = "Baixa e instala os binários do Chromium gerenciados pelo Playwright."
    classpath = sourceSets["e2eTest"].runtimeClasspath
    mainClass.set("com.microsoft.playwright.CLI")
    args("install", "--with-deps", "chromium")
}

Executando a Instalação dos Navegadores

Execute o comando no terminal a partir da raiz do projeto:

1
./gradlew installPlaywrightBrowsers

O Playwright invocará seu utilitário de CLI e efetuará o download do Chromium correspondente:

1
2
3
4
> Task :installPlaywrightBrowsers
Downloading Chromium 133.0.6943.16 (playwright build v1155)...
Download completed 100%
Chromium downloaded to /home/developer/.cache/ms-playwright/chromium-1155

[!TIP]

  • Flag --with-deps: No Linux (Ubuntu/Debian/Fedora), a flag --with-deps instrui o instalador a verificar e instalar pacotes do sistema operacional necessários para a renderização sem interface gráfica (como bibliotecas gráficas libgbm, fontes e suporte ao NSS). Em servidores de CI/CD, isso evita falhas silenciosas de inicialização.
  • Outros Navegadores: Se precisar rodar testes no Firefox ou WebKit (Safari), basta trocar "chromium" por "firefox" ou "webkit", ou omitir o argumento para baixar todos.

4. Escrevendo um Teste End-to-End Mínimo para Validação

Crie o arquivo de teste src/e2eTest/kotlin/com/testwithspring/e2e/PlaywrightSmokeE2ETest.kt para validar a integração do ambiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.testwithspring.e2e

import com.microsoft.playwright.BrowserType
import com.microsoft.playwright.Playwright
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test

@Tag("e2eTest")
class PlaywrightSmokeE2ETest {

    @Test
    @DisplayName("Deve inicializar o Playwright, abrir o Chromium e validar a página")
    fun deveInicializarPlaywrightENavegarComSucesso() {
        // Inicializa o motor do Playwright e o navegador Chromium
        Playwright.create().use { playwright ->
            val browser = playwright.chromium().launch(
                BrowserType.LaunchOptions()
                    .setHeadless(true) // Headless para execuções rápidas e CI/CD
            )

            browser.use { b ->
                val context = b.newContext()
                val page = context.newPage()

                // Acessa uma página web pública ou a URL da sua aplicação Spring Boot
                page.navigate("https://example.com")

                val title = page.title()
                val heading = page.locator("h1").innerText()

                assertThat(title).contains("Example Domain")
                assertThat(heading).isEqualTo("Example Domain")
            }
        }
    }
}

5. Comandos de Execução e Validação dos Relatórios

Com o ambiente configurado, você dispõe dos seguintes comandos de linha para o seu fluxo de desenvolvimento:

1. Executar Isoladamente Apenas a Suíte E2E

Para rodar exclusivamente os testes End-to-End sem reexecutar os testes unitários:

1
./gradlew e2eTest

Ou forçando uma compilação e execução limpas:

1
./gradlew clean e2eTest --info

Saída esperada no terminal:

1
2
3
4
5
6
7
8
> Task :compileKotlin
> Task :compileE2eTestKotlin
> Task :e2eTest

com.testwithspring.e2e.PlaywrightSmokeE2ETest > Deve inicializar o Playwright, abrir o Chromium e validar a página PASSED

BUILD SUCCESSFUL in 4s
1 actionable task: 1 executed

2. Executar Toda a Pirâmide de Testes no Ciclo de Verificação

Para executar a validação completa do projeto (testes unitários e testes E2E):

1
./gradlew check

O Gradle respeitará a diretiva shouldRunAfter(test), executando a suíte test primeiro e a suíte e2eTest em seguida.

3. Validar os Relatórios HTML de Execução

Ao término do comando, o Gradle gera um relatório HTML detalhado e isolado para a suíte E2E em:

1
build/reports/tests/e2eTest/index.html

Você pode abrir o relatório diretamente no navegador:

1
2
3
4
5
# No Linux:
xdg-open build/reports/tests/e2eTest/index.html

# No macOS:
open build/reports/tests/e2eTest/index.html

O relatório discrimina o status de cada método de teste, duração em milissegundos, logs da saída padrão (standard output) e eventuais stacktraces em caso de falha.


6. Execução em Modo com Interface Visível (Headed Mode) para Depuração

Durante o desenvolvimento local de novas telas ou fluxos complexos, você pode desejar acompanhar visualmente o clique e o preenchimento dos campos.

Basta parametrizar a opção de inicialização do navegador com base em uma variável de ambiente:

1
2
3
4
5
6
7
val isHeadless = System.getenv("PLAYWRIGHT_HEADLESS")?.toBoolean() ?: true

val browser = playwright.chromium().launch(
    BrowserType.LaunchOptions()
        .setHeadless(isHeadless)
        .setSlowMo(100.0) // Reduz a velocidade em 100ms por ação para inspeção humana
)

E executar o comando no terminal definindo a variável:

1
PLAYWRIGHT_HEADLESS=false ./gradlew e2eTest

O Chromium será aberto com janela visível na tela, permitindo depuração imediata de seletores e comportamentos da interface gráfica.

Conteúdo