Domando testes instáveis
Troque pausas e corridas por esperas determinísticas, isolamento e quarentena.
Praticante
- flakiness
- e2e
- reliability
Problema
Um teste passa local e falha uma vez em dez no CI. Testes instáveis corroem a confiança até a suíte inteira ser ignorada, o que é pior que não ter suíte.
Solução
A maior parte da instabilidade é uma corrida escondida: o teste confere antes de o app assentar. Espere pela condição observável, nunca por um tempo fixo. Controle o relógio, a rede e a aleatoriedade para cada execução ser determinística, e faça cada teste montar e desmontar os próprios dados.
Quando não der para consertar um teste instável na hora, ponha-o em quarentena (e acompanhe) em vez de repetir às cegas: retentativas silenciosas escondem bugs reais.
Trecho de código
// ❌ Tempo arbitrário: lento e ainda sujeito a corrida
await page.waitForTimeout(2000);
expect(await page.locator('.toast').count()).toBe(1);
// ✅ Asserção web-first, que tenta de novo sozinha
await expect(page.getByText('Saved')).toBeVisible();Armadilhas
- Aumentar as retentativas globais para esconder a instabilidade: isso mascara bugs reais do produto e deixa a suíte lenta.
- Compartilhar estado mutável (linhas de banco, sessão logada) entre testes, criando dependência de ordem.
- Conferir valores sensíveis ao tempo (animações, "há 2 segundos") sem controlar o relógio.