Os testes end-to-end (E2E) verificam o fluxo completo de uma aplicação, desde o que o usuário vê no navegador até os serviços de backend e bancos de dados, confirmando que todas as camadas funcionam corretamente em conjunto. Testes unitários e de integração capturam bugs em componentes isolados, mas podem deixar passar problemas que só aparecem quando o sistema inteiro está em execução. Os testes E2E preenchem essa lacuna.
O Playwright é uma boa escolha para isso. É open-source, mantido pela Microsoft, suporta Chromium, Firefox e WebKit, e tem suporte de primeira classe a TypeScript. Este post cobre os fundamentos dos testes E2E e como implementar uma suite funcional com Playwright.
A Importância dos Testes End-to-End
Testes unitários verificam se uma função retorna o valor correto. Testes de integração verificam se dois módulos trocam dados corretamente. Nenhum deles informa se um usuário consegue de fato fazer login, concluir um checkout ou enviar um formulário sem que algo quebre no caminho.
Testes E2E simulam o comportamento real do usuário: clicar em botões, preencher formulários, navegar entre páginas e verificar se o conteúdo correto é exibido. Eles capturam regressões que cruzam limites de serviços, onde uma mudança em uma API de backend quebra um fluxo de frontend que nenhum teste unitário detectaria.
O contraponto é velocidade e custo de manutenção. Testes E2E rodam mais devagar que testes unitários e são mais sensíveis a mudanças na UI. Execute-os nos caminhos críticos do usuário, não em cada variação menor de componente.
Por que Escolher o Playwright?
O Playwright executa testes no Chromium, Firefox e WebKit a partir de uma única configuração, o que captura diferenças de renderização específicas de cada navegador. Sua espera automática significa que raramente é necessário escrever chamadas explícitas de sleep. Ele captura screenshots, grava traces e gera vídeos em caso de falha, tornando o debug de uma execução falha no CI muito mais rápido do que tentar reproduzir localmente.
O suporte a TypeScript é nativo. Os testes rodam em paralelo entre navegadores. Integra-se de forma limpa com GitHub Actions, GitLab CI e plataformas similares.
Configurando o Ambiente Playwright
Instale o Playwright em um projeto Node.js existente ou novo:
mkdir playwright-e2e-tests
cd playwright-e2e-tests
npm init -y
npm install --save-dev @playwright/test
npx playwright install
npx playwright install baixa os binários dos navegadores para Chromium, Firefox e WebKit. Para projetos TypeScript, inicialize a configuração:
npx tsc --init
Uma estrutura mínima de projeto:
playwright-e2e-tests/
├── tests/
│ └── example.spec.ts
├── package.json
├── tsconfig.json
└── playwright.config.ts
Um Teste Básico de Exemplo
import { test, expect } from '@playwright/test';
test('homepage has expected title and welcome message', async ({ page }) => {
await page.goto('https://example.com');
// Check the page title
await expect(page).toHaveTitle(/Example Domain/);
// Check if 'Example Domain' text is present
const heading = await page.locator('h1');
await expect(heading).toContainText('Example Domain');
});
O Playwright aguarda automaticamente o carregamento da página e que os elementos estejam prontos antes de interagir com eles. O teste navega para uma URL, verifica o título e verifica o cabeçalho. Execute-o com:
npx playwright test
Configuração Avançada do Playwright
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: 'tests',
timeout: 30000,
expect: {
timeout: 5000,
},
use: {
headless: true,
screenshot: 'only-on-failure',
trace: 'on-first-retry',
},
projects: [
{
name: 'Chromium',
use: { browserName: 'chromium' },
},
{
name: 'Firefox',
use: { browserName: 'firefox' },
},
{
name: 'WebKit',
use: { browserName: 'webkit' },
},
],
});
testDir define onde ficam os arquivos de teste. timeout limita cada teste a 30 segundos. screenshot: 'only-on-failure' e trace: 'on-first-retry' fornecem artefatos de debug sem poluir as execuções bem-sucedidas. O array projects executa os mesmos testes nos três motores de navegador em paralelo.
Testando Aplicações Dinâmicas e Autenticação
Aplicações de página única frequentemente requerem uma sessão autenticada antes que qualquer teste significativo possa ser executado. Fazer login antes de cada teste é lento. O Playwright resolve isso com o estado de armazenamento: faça login uma vez em uma etapa de setup global, salve a sessão e reutilize-a nos testes.
// global-setup.ts
import { test as setup, expect } from '@playwright/test';
setup('authenticate once', async ({ page }) => {
await page.goto('https://my-app.com/login');
await page.fill('#username', 'testuser');
await page.fill('#password', 'testpassword');
await page.click('button[type="submit"]');
// Wait for a known element after login
await expect(page.locator('#dashboard')).toBeVisible();
// Save state
await page.context().storageState({ path: 'authState.json' });
});
Então em playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
globalSetup: require.resolve('./global-setup'),
use: {
storageState: 'authState.json',
},
// ... other configurations
});
Todos os testes subsequentes iniciam com a sessão salva. Sem fluxos de login repetidos, sem tempo adicional de teste para autenticação.
Depurando Testes E2E com Falha
Quando um teste falha no CI, você precisa de informações. As ferramentas integradas do Playwright cobrem os principais cenários:
Screenshots em caso de falha mostram exatamente o que o navegador exibiu quando o teste falhou. Os traces capturam uma linha do tempo completa de cada ação, requisição de rede e mensagem de console. Executar com --headed localmente permite acompanhar a execução do teste em uma janela real do navegador e inspecionar o DOM.
test('debugging example', async ({ page }) => {
await page.goto('https://example.com');
// Intentionally failing step
await expect(page.locator('.non-existent')).toBeVisible();
});
Para executar com tracing ativado:
npx playwright test --headed --trace=on
Integração com CI/CD e DevOps
Um workflow básico para o GitHub Actions:
name: Playwright E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Install browsers
run: npx playwright install
- name: Run tests
run: npx playwright test
Cada push executa a suite E2E completa. Testes com falha produzem screenshots e traces como artefatos do CI, que você pode baixar e inspecionar sem precisar reproduzir localmente.
Boas Práticas para Playwright e Testes E2E
Escreva testes que não dependam da ordem de execução. Cada teste deve configurar seu próprio estado de forma independente. Um teste que depende de um teste anterior ter sido executado é frágil e difícil de depurar quando falha.
Use atributos data-test-id nos elementos em vez de seletores CSS vinculados a nomes de classe. Classes CSS mudam quando os designs são atualizados. Atributos de teste são contratos explícitos entre o teste e a UI.
Cubra seus fluxos de usuário mais importantes: login, ações de negócio principais, checkout, envio de formulários. Não tente testar E2E cada variação menor da UI. Mantenha os testes E2E focados em caminhos que atravessam múltiplas camadas.
Limpe os dados de teste após cada execução se seus testes escrevem em um banco de dados. Ambientes de teste efêmeros são mais fáceis de raciocinar do que ambientes com estado acumulado.
Expandindo Além dos Cenários Básicos
O Playwright lida com mais do que simples verificações de página. Você pode emular dispositivos móveis e testar layouts responsivos. Pode interceptar requisições de rede e simular respostas de APIs de terceiros para evitar disparar pagamentos reais ou e-mails durante os testes. Testes de regressão visual com snapshots capturam mudanças não intencionais de estilo. Para testes de API, você pode usar o contexto de requisição do Playwright para acessar endpoints diretamente enquanto reutiliza o mesmo estado de autenticação.
Conclusão
Testes E2E com Playwright conferem confiança de que os fluxos de usuário mais importantes da sua aplicação funcionam de ponta a ponta, em múltiplos navegadores e em condições próximas à produção. Eles não substituem testes unitários ou de integração, mas capturam uma categoria de bugs que esses testes não conseguem detectar. Com execução paralela no Chromium, Firefox e WebKit, bons artefatos de falha e integração limpa com CI, o Playwright torna os testes E2E algo prático em vez de um fardo.