Pular para o conteudo principal

Flaky Tests: por que Acontecem e Como Reduzir

Teste flaky não é só irritação de pipeline. É um sinal de ambiente, acoplamento, concorrência ou espera mal controlada que faz o time perder confiança no feedback.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

O problema

Todo time que roda teste por tempo suficiente encontra isso:

  • o teste falha no CI e passa local
  • falha uma vez e passa na segunda
  • quebra mais quando roda em paralelo
  • fica “vermelho sem motivo” perto de release

O nome bonito é flaky test.

O efeito real é pior do que parece.

Porque o time para de confiar no feedback.

Quando isso acontece, cada falha vira discussão:

  • “quebrou mesmo ou é só o teste de novo?”
  • “manda rerun”
  • “depois a gente arruma”

E pronto. A suíte deixa de proteger e começa a cansar.

Modelo mental

Pense assim:

flaky test é um teste com fonte de não determinismo que o time não controla direito.

Essa definição é melhor do que “teste instável”.

Porque força a pergunta certa:

o que neste teste depende de algo que muda entre uma execução e outra?

Geralmente a resposta cai em uma destas categorias:

  • tempo
  • concorrência
  • ordem de execução
  • estado vazando entre testes
  • dependência externa
  • UI ainda não pronta quando o teste olha

Ou seja, o problema quase nunca é azar.

É falta de controle sobre uma variável importante.

Quebrando o problema

Tempo é um gerador clássico de flakiness

Quando o teste depende de:

  • setTimeout
  • animação
  • debounce
  • retry automático
  • job assíncrono

ele pode observar o sistema cedo demais ou tarde demais.

O erro comum é resolver isso com timeout maior.

Às vezes ajuda por um dia.

Mas não corrige a causa.

O melhor caminho costuma ser controlar relógio, esperar o sinal certo ou testar em um nível mais apropriado.

Estado compartilhado vira armadilha silenciosa

Teste que depende de cache global, banco não limpo, variável estática, fila reaproveitada ou usuário reutilizado costuma falhar de forma intermitente.

Especialmente quando a suíte passa a rodar em paralelo.

Se um teste deixa lixo para o próximo, o problema não é azar.

O problema é isolamento ruim.

Dependência externa enfraquece previsibilidade

Se o teste depende de:

  • API real
  • rede instável
  • clock do sistema
  • serviço de terceiro
  • dado que muda fora do seu controle

ele já começou mais fraco.

Nem todo teste precisa ser totalmente isolado.

Mas todo teste precisa ter uma razão clara para depender de algo externo.

Se essa razão não existe, você está comprando instabilidade sem necessidade.

Concorrência e paralelismo expõem defeitos escondidos

Tem teste que “funciona” sozinho e quebra quando roda junto com os outros.

Isso é um sinal ótimo.

Ele está mostrando que há competição por recurso, ordem implícita ou acoplamento invisível.

O erro é desligar o paralelismo e fingir que o problema sumiu.

Às vezes até faz sentido como mitigação temporária.

Mas a análise precisa continuar.

Seletor frágil é flaky test disfarçado de teste de UI

No frontend isso aparece o tempo todo:

  • seletor baseado em texto muito volátil
  • elemento ainda não renderizou
  • loading troca rápido demais
  • teste clica antes da UI ficar interativa

O teste não está validando comportamento.

Está brigando com detalhes de renderização.

Exemplo simples

Imagine um teste de checkout que:

  1. clica em “Finalizar”
  2. espera 2 segundos
  3. procura a mensagem “Pedido criado”

Às vezes passa. Às vezes falha.

Por quê?

Porque o teste assumiu que 2 segundos sempre bastam.

Mas o sistema pode variar por:

  • fila mais lenta
  • renderização mais lenta no CI
  • máquina concorrida
  • resposta de rede diferente

Versão melhor:

  1. clicar em “Finalizar”
  2. esperar um sinal observável de conclusão
  3. validar o estado final

Esse sinal pode ser:

  • request concluída
  • toast visível
  • botão desabilitado e depois reabilitado
  • redirecionamento concluído

Repara na diferença.

O teste sai do “vou torcer para já ter terminado” e vai para “vou observar o evento certo”.

Erros comuns

  • Tratar flaky test como problema menor porque “é só rodar de novo”.
  • Resolver tudo com timeout maior.
  • Misturar teste de comportamento com detalhe interno de implementação.
  • Aceitar dependência externa real sem motivo forte.
  • Desligar paralelismo para sempre sem entender o vazamento de estado.
  • Marcar teste instável como skip e chamar isso de solução.

Como um senior pensa

Quem tem mais maturidade não pergunta só:

“Como faço esse teste parar de falhar?”

Pergunta melhor:

“Qual variável não controlada está tornando este feedback não confiável?”

Isso muda a qualidade da investigação.

Porque flaky test é problema de confiabilidade do processo de engenharia.

Não é só problema de teste isolado.

Se a suíte mente, o time aprende a ignorar alerta verdadeiro junto com o falso.

O que o entrevistador quer ver

Em entrevista, não basta dizer “flaky test é ruim”.

Isso é o mínimo.

O que pesa é mostrar método.

Uma resposta forte costuma cobrir:

  • definição prática de flakiness
  • fontes comuns de não determinismo
  • como isolar a causa
  • quando mitigar rápido e quando fazer correção estrutural

Uma resposta forte pode soar assim:

“Eu trato flaky test como perda de confiança no feedback. Primeiro tento classificar a causa: tempo, estado compartilhado, concorrência, rede ou seletor frágil. Depois reduzo variáveis, reproduzo com mais controle e corrijo a fonte de não determinismo. Se precisar, faço uma mitigação temporária, mas não normalizo rerun como solução.”

Flaky test não é azar. É engenharia mal controlada aparecendo na superfície.

Quando o time para de confiar na suíte, ele também para de aprender com ela.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Próximo artigo Mock Demais: Quando o Teste Para de te Proteger Artigo anterior Como Falar sobre Estratégia de Testes em Entrevista

Continue explorando

Artigos relacionados