Flaky Tests: O Problema Não São os Testes, É a Confiança
Um desenvolvedor aperta "merge". O pipeline fica vermelho. Ele clica em "re-run". Passa verde. Merge feito. Ninguém investiga.
Esse cenário se repete milhões de vezes por dia em empresas ao redor do mundo. E é exatamente aí que mora o problema: não são os testes que estão quebrados — é a confiança no pipeline que se destruiu.
Os Números Que Ninguém Quer Ver
- Google: 1,5 milhão de reruns de testes flaky por dia no pico
- Atlassian: 21% das falhas no master branch são causadas por flaky tests — totalizando 150.000 horas de desenvolvedores desperdiçadas por ano
- SAP HANA: Análise de 559 reports de flakiness mostrou que 23% são causados por problemas de concorrência
- Exact: Uma empresa com 2.000 funcionários e 25.000 testes diários tinha taxa de sucesso de pipeline de apenas 27% antes de atacar flakiness
Flaky tests não são uma inconveniência técnica. São um problema de economia de entrega. E ele se compõe.
O Ciclo da Desconfiança
O ciclo é previsível e acontece em 6-8 semanas:
Semana 1-2: Flaky tests começam a aparecer. Desenvolvedos culpam seu próprio código. Semana 3: Eles percebem o padrão — mesmos testes, mesmas falhas, nada a ver com suas mudanças. Semana 6: Mentalmente, desistiram. Toda a suíte se torna suspeita, inclusive os testes que funcionam perfeitamente. Semana 8: O pipeline perde toda credibilidade. O que antes era uma barreira de qualidade vira um obstáculo irritante.O indicador-chave? Taxa de re-run. Quando desenvolvedores clicam "retry" em mais de 30% dos seus PRs, eles não estão testando — estão apostando. Abaixo de 30%, eles confiam que a falha é deles. Acima de 30%, confiam que a falha é da infraestrutura.
As 5 Causas Raiz (Nenhuma É "Azar")
Flakiness quase nunca é aleatório. Há padrões identificáveis:
1. Corridas de Tempo (Timing Races)
A causa mais comum. Um sleep(5000) hardcoded que funciona 99% do tempo, mas falha quando o CI está sob carga. Ou uma.assert que verifica o estado antes da UI terminar de renderizar.
// RUIM — depende de timing fixo
await page.waitForTimeout(2000);
expect(await page.textContent('.result')).toBe('Sucesso');
// BOM — espera pela condição real
await expect(page.locator('.result')).toHaveText('Sucesso');
Playwright resolve isso com auto-wait nativo. Cypress tem retry automático de comandos. Mas a regra universal é: nunca asserte em um timer, sempre no estado estabelecido.
2. Estado Compartilhado (Test Interdependence)
O teste A cria um registro no banco. O teste B depende desse registro. O teste C deleta algo que o teste D precisa. Resultado: a ordem de execução determina se o build passa ou falha.
RUIM — fixture global compartilhada
@pytest.fixture(scope="session")
def db_connection():
return create_connection()
BOM — isolamento por teste
@pytest.fixture
def db_connection():
conn = create_connection()
yield conn
conn.rollback() # Limpa tudo após o teste
Teste de sanidade: Se você embaralhar a ordem dos testes e o suite quebrar, existe acoplamento oculto que retries esconderiam pra sempre.
3. Ambiente Instável (Environment Flakiness)
APIs externas com latência variável, containers que demoram para subir, dados de teste compartilhados entre pipelines. Um estudo do Docker descobriu que após um ano tentando consertar testes individualmente, a estabilidade não melhorou — até que investiram na infraestrutura do ambiente de teste.
4. Dependências de Rede
Chamadas HTTP reais em testes E2E. Timeouts que variam dependendo da carga do servidor. Webhooks que chegam antes ou depois do esperado.
5. Animações e Transições
Elementos que estão em transição CSS quando o teste tenta interagir. Modais que estão animando abrindo. Toasts que somem após 3 segundos.
Por Que Retries São o Pior Remédio
A indústria tratou flaky tests como um problema de agendamento. Retry 3 vezes, se passar, tá verde. Mas retries não consertam — escondem.
| Dimensão | Retries às cegas | Quarantine + fix | |---|---|---| | Sinal de falha | Oculto, descartado | Preservado e classificado | | Tempo/custo de CI | Cresce silenciosamente | Diminui com o tempo | | Confiança no deploy | Verde falso, bugs passam | Verde confiável | | Causas raiz | Se acumulam | Caminham a zero | | Confiança do dev | Erosiona | Se restaura
O pior cenário: um teste que falha 20% do tempo passa quase sempre com política de 3 retries. Parece estável, mas não é. Quando finalmente deixa passar uma regressão real no retry "sortudo", vocêshipa o bug confiando no checkmark verde.
Um pipeline com taxa de retry de 15% e pass rate de 98% não é um pipeline saudável. É um pipeline com um problema de confiança escondido.
A Estratégia de Quarantine
A alternativa aos retries é o quarantine — isolar testes flaky sem deletá-los, mantendo visibilidade enquanto resolve a causa raiz.
Como Implementar
1. Detectar automaticamenteRegistre resultados por teste, por commit SHA. Um teste que passa E falha no mesmo SHA é flaky por definição.
Exemplo de detecção via histórico
def is_flaky(test_name, sha, results):
statuses = [r.status for r in results if r.test == test_name and r.sha == sha]
return 'pass' in statuses and 'fail' in statuses
2. Separar em duas suítes
- Blocking suite: testes estáveis. Falha aqui bloqueia o merge.
- Quarantine suite: testes flaky conhecidos. Executam, mas não bloqueiam.
Cada teste em quarantine tem um dono e um ticket. Prazo máximo: 30 dias. Depois disso: consertar ou deletar com justificativa.
4. Monitorar- Tamanho do quarantine ao longo do tempo (crescendo = problema)
- Dias em quarantine por teste (máximo 30)
- Taxa de entrada/saída (fluido = saudável)
Resultado Real
A Exact aplicou essas intervenções e elevou a taxa de sucesso do pipeline de 27% para 96%. O segredo não foi consertar todos os testes — foi classificar, isolar e atacar as causas raiz: tarefas de banco redundantes (40% das falhas) e dados de teste poluídos (22%).
Métricas Que Importam
Esqueça pass rate. Essas métricas contam a verdadeira história:
| Métrica | Como calcular | Meta | |---|---|---| | Flake rate | Testes com pass/fail misto no mesmo commit / total | < 2% | | Taxa de retry | Jobs que passam só no retry / total de jobs | < 2% | | Quarantine % | Testes em quarantine / total de testes | < 5% | | Custo de retry | Minutos de retry / minutos totais de CI | < 10% | | Tempo para confiança | Tempo até o dev confiar que o merge é seguro | < 10 min |
O Que a Pesquisa Diz Sobre IA e Flakiness
Um dado que pega desprevenido: testes gerados por IA aumentam a taxa de flakiness. LLMs são competentes em gerar scaffolding de testes, mas frequentemente criam asserts frágeis — dependência de timing, assumptions hardcoded sobre o ambiente, e mocks excessivamente específicos.
Antes de jogar um Copilot na suíte de testes, modernize a infraestrutura de teste primeiro. Caso contrário, você vai aumentar a taxa de flakiness com confiança.
Aprender com Google, Atlassian e SAP
Google descobriu que 84% das transições de pass para fail vêm de flakiness, não de bugs reais. Isso significa que quase toda falha que seu time investiga é fantasma. Atlassian quantificou o custo: 150.000 horas/ano desperdiçadas. Quando flaky tests causam 21% das falhas no master, o problema não é mais técnico — é financeiro. SAP HANA analisou 559 reports de flakiness usando LLMs como anotadores. Concorrência (23%), timeouts (18%), e fragilidade de oráculos (11%) foram as principais causas. Cada tipo de teste enfrenta desafios diferentes.Conclusão: Trust Over Green
Um build verde que ninguém acredita é pior que nenhum build. Porque ele fornece confiança falsa no exato momento em que você precisa de confiança real: enviando para produção.
A regra é simples:
1. Pare de medir pass rate. Meça taxa de retry. 2. Pare de consertar cada flaky test. Quarantine os piores 5%. 3. Pare de celebrar builds verdes. Celebre pipelines confiáveis. 4. Nunca faça retry de vermelho para verde. Isso é mentira.
Confiança não é binária. Não se perde gradualmente — despenha de um penhasco. E recuperá-la é muito mais difícil do que perdê-la.
Seu pipeline mente? A resposta define se você pode confiar na sua automação ou se está apenas apertando botões.
---
Baseado em pesquisas do Google, Atlassian, SAP, Exact, Docker, e artigos de DevOps.com, SD Times, e ContextQA (2026).