Em uma suite de 1.000 testes rodando CI 20 vezes por dia, 5% de flakiness custa 15 a 20 horas de engenharia por semana em reruns e investigação. Isso é antes de contabilizar a erosão de confiança: quando os engenheiros descartam falhas como "provavelmente flaky", bugs reais são publicados. A arquitetura de auto-waiting do Playwright produz taxas de 12% de flakiness contra 28% do Selenium em times pesquisados. Cada clique e assertion espera os elementos estarem prontos em vez de exigir utilitários manuais de wait.

O que testes flaky realmente custam

Um teste flaky é aquele que produz resultados diferentes no mesmo código: passando às vezes, falhando outras, sem razão determinística.

O custo visível: um engenheiro vê um teste falhando, roda de novo, ele passa, marca como "flaky" e segue em frente. Cinco minutos perdidos.

O custo invisível é maior:

Perda de confiança na suite. Uma vez que os engenheiros sabem que alguns testes são flaky, eles começam a tratar falhas como "provavelmente flaky" por padrão. Falhas reais são descartadas. Bugs são publicados. A suite de testes virou ruído. Overhead de reruns. Uma suite de testes com 10% de testes flaky configurada para retry 3 vezes efetivamente roda 130% dos seus testes em cada execução de CI. Em uma suite de 30 minutos, são 9 minutos por execução, horas por dia em um time. Tempo de desenvolvedor em investigação. Cada nova falha exige que alguém decida: isso é flaky ou é real? Essa decisão leva de 5 a 30 minutos de investigação. Com 10 falhas flaky por dia, são uma hora de tempo de engenharia diariamente. Atrasos de release. Se o seu CI está configurado para bloquear deploy em falha de teste (como deveria estar), testes flaky viram bloqueadores de release. O workaround (desabilitar os testes) remove cobertura em que você estava contando. Estimativa quantificada: Um time com 5% de flakiness em uma suite de 1.000 testes rodando CI 20 vezes por dia provavelmente gasta 15 a 20 horas de engenharia por semana em overhead. A $60/hora de custo totalmente carregado, isso é $900 a $1.200 por semana, ou $50.000 a $60.000 por ano.

Não é teórico. O Google publicou um estudo em 2016 mostrando que 1 em cada 7 testes no monorepo deles apresentava flakiness em algum ponto. Os números na maioria das empresas são piores, não melhores.

As causas mais comuns de testes flaky

Antes de comparar frameworks, entenda o que realmente causa flakiness:

Race conditions contra UI assíncrona. O teste clica em um botão e imediatamente verifica um resultado que ainda não carregou. O timing funciona em uma máquina rápida, falha em um servidor de CI mais lento. Estado de teste compartilhado. O Teste A cria dados, o Teste B os lê, o Teste C os deleta. Se rodarem em ordem diferente ou em paralelo, eles interferem entre si. Timing de ambiente. O teste passa localmente (SSD rápido, rede rápida) mas falha no CI (máquina mais lenta, latência de rede para o ambiente de teste). Atrasos de animação. Uma animação CSS está completando enquanto o teste está tentando interagir com o elemento animado. Timing de rede. Uma chamada de API leva 500ms em média mas ocasionalmente leva 2000ms. O timeout do teste está definido para 1000ms. Dependências externas. Testes que falam com serviços reais de terceiros (processadores de pagamento, provedores de email) são flaky sempre que esses serviços têm problemas.

Como a arquitetura do Playwright reduz flakiness

O Playwright foi projetado do zero com o problema de flakiness em mente. Os dois mecanismos-chave:

Auto-waiting

Toda ação e assertion do Playwright espera automaticamente o elemento alvo estar no estado certo antes de prosseguir.

page.click() espera o elemento:
  • Existir no DOM
  • Estar visível
  • Não estar coberto por outro elemento
  • Não estar animando
  • Estar habilitado
expect(locator).toBeVisible() aguarda até o timeout configurado para a assertion se tornar verdadeira.

Isso elimina a fonte mais comum de flakiness: a race condition de "o elemento existe mas ainda não está pronto." Você não adiciona chamadas waitForSelector em todo lugar. Você só escreve click e o Playwright cuida da espera.

Assertions web-first

A biblioteca de assertions do Playwright (expect) foi construída para UIs assíncronas. Quando você escreve:

await expect(page.getByText('Sucesso')).toBeVisible();

Isso não tira um snapshot do estado e verifica uma vez. Ele faz polling do DOM repetidamente até a assertion se tornar verdadeira, ou até o timeout expirar. O timeout padrão é 5 segundos.

Compare com uma assertion ingênua:

// Flaky — verifica o estado neste exato momento, não quando se torna verdadeiro
const text = await page.textContent('.message');
expect(text).toBe('Sucesso');

A versão Playwright faz retry; a ingênua não. A maior parte da flakiness em suites baseadas em Selenium vem do padrão ingênuo, porque o Selenium não tem assertions com retry integrado.

Playwright vs Selenium: comparação de flakiness

É aqui que a diferença arquitetural aparece em números reais.

A comparação pública mais abrangente é o relatório Checkly State of Testing 2024, que pesquisou aproximadamente 1.500 times de engenharia:

  • Times usando Playwright reportaram 12% dos seus testes como regularmente flaky
  • Times usando Selenium reportaram 28% regularmente flaky
  • Times usando Cypress reportaram 18% regularmente flaky

A metodologia importa: "regularmente flaky" significa que o time identificou o teste como flaky e está contornando o problema. Muitos mais testes são intermitentemente flaky mas ainda não foram sinalizados.

A diferença se resume a algumas coisas específicas:

O Selenium exige waits explícitos. driver.findElement(By.id("result")) falha imediatamente se o elemento não estiver presente. Times experientes em Selenium adicionam chamadas WebDriverWait em todo lugar. Times inexperientes não adicionam, ou não adicionam de forma consistente, e os testes ficam flaky. Os waits padrão do Playwright são apropriados para SPAs modernas. Aplicações React e Vue renderizam de forma assíncrona. O auto-waiting do Playwright foi projetado para isso. O Selenium foi projetado para páginas tradicionais renderizadas no servidor e adaptado para SPAs; a adaptação aparece. A interceptação de rede do Playwright é integrada. Mockar respostas de API para tornar os testes determinísticos é uma feature de primeira classe no Playwright. No Selenium, exige tooling adicional (BrowserMob Proxy, etc.) que adiciona complexidade e seus próprios modos de falha.

O custo real da flakiness do Selenium na prática

Um time migrando do Selenium para o Playwright em uma empresa SaaS de médio porte documentou sua experiência:

Antes da migração:

  • 1.200 testes Selenium
  • ~180 testes marcados como "flaky conhecidos" (15%)
  • Tempo de execução do CI: 45 minutos com 3 retries
  • ~8 horas de engenharia por semana em investigação de flakiness
  • Testes desabilitados por flakiness: 47 (4%)

Após migração para Playwright (6 meses depois):

  • 1.200 testes migrados, ~200 novos testes adicionados
  • ~40 testes marcados como flaky (2,5%)
  • Tempo de execução do CI: 22 minutos com 1 retry
  • ~1 hora de engenharia por semana em flakiness
  • Testes desabilitados: 5 (0,3%)

A redução no tempo de execução veio parcialmente do Playwright ser mais rápido (execução paralela, sem overhead do WebDriver), mas em grande parte de precisar de menos retries.

Como medir seu custo atual de flakiness

Antes de corrigir flakiness, meça-a. A maioria dos sistemas de CI rastreia isso se você sabe onde olhar.

GitHub Actions: Verifique os artefatos de relatório de teste. A maioria dos reporters do Playwright inclui um status "flaky" para testes que passaram no retry. HTML reporter do Playwright: Adicione ao playwright.config.ts:

reporter: [['html', { open: 'never' }]],

O relatório HTML marca testes que passaram no retry. Esses são seus testes flaky.

Rastreamento manual: Rode sua suite de testes 10 vezes contra o mesmo commit. Qualquer teste que não produzir o mesmo resultado cada vez é flaky. É tedioso mas definitivo. Calcule o custo:

1. Conte o número de testes flaky únicos

2. Estime o tempo médio de investigação por falha (geralmente 10 a 20 minutos)

3. Estime com que frequência cada teste flaky falha por semana

4. Multiplique: (falhas de teste flaky por semana) × (minutos por investigação) / 60 = horas de engenharia por semana

Para a maioria dos times, esse número surpreende.

Corrigindo testes flaky no Playwright

Quando você tem testes flaky em uma suite Playwright, a abordagem de diagnóstico:

Passo 1: Rode com trace ativado

// playwright.config.ts
use: {
  trace: 'on-first-retry',
}

No retry, o Playwright grava um trace completo: screenshots, requisições de rede, snapshots do DOM, output do console. Abra com npx playwright show-trace trace.zip.

Passo 2: Identifique o ponto de falha

O trace mostra exatamente onde o teste falhou e qual era o estado da página. Geralmente um de:

  • Elemento ainda não estava visível
  • Requisição de rede não havia completado
  • Teste anterior deixou estado que afetou este
Passo 3: Corrija com assertions web-first

Substitua padrões frágeis:

// Frágil
await page.waitForTimeout(2000);
await page.click('.submit-button');

// Robusto
await page.getByRole('button', { name: 'Submit' }).click();
// Auto-waiting cuida do timing

Passo 4: Corrija estado compartilhado

Cada teste deve configurar seus próprios dados e não depender de outros testes. Use hooks beforeEach e chamadas de API para criar o estado que cada teste precisa.

test.beforeEach(async ({ request }) => {
  // Criar um usuário novo para cada teste via API
  await request.post('/api/users', { data: { email: 'test@example.com' } });
});

FAQ

Temos 500 testes Selenium. A migração para Playwright vale a pena?

Para a maioria dos times: sim, se flakiness é um problema real. O cronograma de migração é de aproximadamente 2 a 4 semanas de tempo de engenharia para 500 testes, dependendo da complexidade. As economias contínuas (menos tempo de CI, menos tempo de investigação, suite mais confiável) geralmente se justificam em poucos meses.

Nossos testes Playwright ainda são flaky. O que estamos fazendo de errado?

A maioria da flakiness no Playwright vem de estado de teste compartilhado (testes dependendo uns dos outros) ou de contornar o auto-waiting com chamadas waitForTimeout. Procure setTimeout e waitForTimeout nos seus arquivos de teste. Substitua cada um por uma assertion adequada.

Qual é uma meta razoável de flakiness?

Abaixo de 2% é alcançável. Abaixo de 1% para uma suite bem mantida é realista. Zero é o objetivo; 0,5% é bom. Acima de 5% significa que flakiness está afetando a produtividade do time e a suite está perdendo credibilidade.

O auto-waiting do Playwright elimina todas as race conditions?

Não. Ele elimina as mais comuns (elemento não pronto para interação, assertion falhando porque o resultado ainda não apareceu). Race conditions na sua lógica de teste (testes que dependem uns dos outros, testes que compartilham estado de banco de dados) não são resolvidas pelo framework. Essas exigem isolamento de testes.

→ Veja também: Depurando Testes Instáveis: Um Guia Prático | Playwright vs Cypress vs Selenium em 2026: Comparação Honesta