🚀 7 erros comuns em automação de testes (e como evitar)

Se você trabalha como QA a muito tempo ou começou na automação de testes recentemente provavelmente já passou por isso:

  • 👉 testes que quebram do nada
  • 👉 scripts difíceis de manter
  • 👉 automação que mais atrapalha do que ajuda

A verdade é que a maioria dos problemas em automação vem de erros básicos.

Neste artigo, você vai ver os 7 erros mais comuns em automação de testes e como evitá-los na prática.


❌ 1. Automatizar tudo (sem definir nenhum critério)

🚨 O problema: Tentar alcançar "100% de cobertura de automação" e sair automatizando inclusive fluxos instáveis, telas em construção ou funcionalidades que mudam de regra a cada sprint.

💡 Exemplo prático: Imagine automatizar os testes de tela de um novo checkout durante uma promoção de Black Friday, onde o time de design altera a posição dos botões e os cupons a cada 2 dias. Os scripts de automação vão quebrar continuamente (os chamados flaky tests), e o QA vai passar mais tempo dando manutenção no código do teste do que encontrando falhas reais.

✅ Como evitar:

  • Automatize fluxos críticos: Foque no "caminho feliz" indispensável (ex: Login, Checkout consolidado, Cadastro de usuário).
  • Prefira cenários estáveis: Funcionalidades maduras e com regras de negócio consolidadas.
  • Foque no que é repetitivo: Testes de regressão que precisam rodar em toda nova versão do sistema.
Regra de Ouro: Se a funcionalidade muda toda hora, mantenha nos testes manuais e não automatize (ainda).

❌ 2. Não ter estratégia de testes

🚨 O problema: Abrir a IDE e começar a escrever scripts de automação sem nenhum planejamento prévio. Isso gera uma suíte de testes bagunçada, duplicada, difícil de dar manutenção e que quase ninguém no time confia.

💡 Exemplo prático: Um projeto que automatiza 50 fluxos completos apenas pela interface gráfica (UI) usando Selenium/Playwright sem usar a Pirâmide de Testes. O resultado? A suíte demora 3 horas para rodar na esteira de CI/CD, quebra por instabilidade de rede e o time passa a ignorar os relatórios de execução por achar que a falha é "só instabilidade do teste".

✅ Como evitar:

  • Respeite a Pirâmide de Testes: Baseie a maioria das validações em testes de unidade e API (mais rápidos e baratos) e deixe para a UI apenas os fluxos ponta a ponta (E2E) essenciais.
  • Defina o escopo e as prioridades: Mapeie com o time de produto quais cenários realmente trazem risco de negócio se falharem.
  • Escolha a ferramenta adequada: Selecione o framework baseado na stack do projeto e na habilidade da equipe, não apenas por moda.
Regra de Ouro: Uma automação sem estratégia é apenas um script caro gerando falsos positivos na sua esteira de integração.

❌ 3. Criar testes dependentes entre si

🚨 O problema: Estruturar a suíte de forma que um teste precise da execução bem-sucedida do teste anterior para funcionar. Essa dependência em cadeia cria um "efeito dominó": se o primeiro teste falha por uma instabilidade momentânea, todos os testes subsequentes quebram em cascata.

💡 Exemplo prático: O Teste 2 (Editar Perfil) e o Teste 3 (Deletar Conta) dependem obrigatoriamente do Teste 1 (Criar Usuário) rodar primeiro. Se o envio do e-mail de confirmação no Teste 1 oscilar e falhar, os testes 2 e 3 serão marcados como falha sem ao menos terem sido executados de verdade, gerando relatórios imprecisos e desperdício de tempo na investigação.

✅ Como evitar:

  • Garanta a independência total (Atomicidade): Cada teste deve ser capaz de rodar sozinho, em qualquer ordem e em ambientes paralelos.
  • Utilize ganchos de Setup e Teardown: Use blocos como beforeEach e afterEach para preparar o estado da aplicação antes de cada teste e limpar os dados ao final.
  • Crie dados isolados via API: Em vez de criar o usuário pela interface gráfica no início de cada teste, utilize requisições diretas de API no setup para gerar um usuário único e acelerar a execução.
Regra de Ouro: Se o seu teste não consegue rodar sozinho e de forma isolada às 3 horas da manhã em qualquer ordem, ele precisa ser refatorado.

❌ 4. Uso excessivo de esperas fixas (Hardcoded Waits)

🚨 O problema: Pausar a execução do teste por um tempo arbitrário e fixo (como "esperar 5 segundos"). Isso deixa a suíte extremamente lenta e, pior, não garante que o elemento estará pronto quando o tempo acabar, gerando instabilidade constante (flakiness).

💡 Exemplo prático: Definir uma espera fixa de 5 segundos para o carregamento de uma listagem de produtos. Se a API responder em 500ms, você jogou 4,5 segundos no lixo. Se a rede oscilar e a API demorar 5,1 segundos, o teste vai falhar. Multiplique isso por 100 testes e sua suíte demorará horas sem necessidade.

❌ Como NÃO fazer:

// Evite: pausa forçada e desnecessária
await page.waitForTimeout(5000);

✅ Como evitar:

Utilize esperas explícitas e dinâmicas (esperar até que o elemento esteja visível ou clicável) ou aproveite os recursos de auto-waiting nativos de frameworks modernos como Playwright e Cypress.

// Ideal: espera dinâmica baseada no estado do elemento
await expect(page.getByRole('button', { name: 'Salvar' })).toBeVisible();
Regra de Ouro: Nunca force o script a "dormir" por tempo fixo. Espere por eventos reais da aplicação, como a requisição finalizar ou o elemento aparecer na tela.

❌ 5. Utilização de seletores frágeis

🚨 O problema: Mapear elementos da tela utilizando caminhos absolutos do DOM ou classes genéricas de estilização CSS. Qualquer pequena alteração visual no layout quebra o teste, mesmo que a funcionalidade continue perfeita.

💡 Exemplo prático: Mapear o botão de confirmação usando o caminho da árvore HTML ou classes geradas por frameworks como Tailwind ou Styled Components (ex: .btn-primary-2x8a). Quando o desenvolvedor altera a cor do botão ou adiciona uma <div> em volta para ajuste de margem, o teste quebra.

❌ Como NÃO fazer:

// Evite: caminho absoluto frágil
page.locator('div > div:nth-child(2) > span > button');

✅ Como evitar:

Adote a boas práticas de priorização de seletores: priorize acessibilidade (padrão de ferramentas modernas) ou atributos customizados criados exclusivamente para testes.

// Ideal: usando acessibilidade ou atributo exclusivo de teste
page.getByTestId('login-button');
Regra de Ouro: Seletores de teste devem refletir a intenção do usuário (acessibilidade) ou usar atributos dedicados (como data-testid). Nunca amarre seu teste à estrutura estritamente visual do CSS.

❌ 6. Misturar muita lógica no teste

🚨 O problema: Encher o arquivo do teste com condicionais (if/else), laços de repetição (for/while) e manipulação complexa de dados. O script deixa de ser um teste e vira um "minisistema" dentro da automação, tornando a leitura confusa e a manutenção um pesadelo.

💡 Exemplo prático: Criar um script onde o teste faz um if para checar se o usuário já existe no banco, um for para percorrer uma tabela HTML e buscar o e-mail, e vários try/catch para tratar exceções. Se o teste falhar, o QA precisa debugar o próprio código do teste durante horas para descobrir se a falha foi no software ou na lógica mirabolante que ele criou.

✅ Como evitar:

  • Siga o padrão AAA (Arrange, Act, Assert): O arquivo do teste deve apenas preparar os dados, executar a ação e validar o resultado final de forma clara.
  • Encapsule a complexidade: Mova requisições auxiliares, conexões com banco de dados e geradores de massa de testes para funções utilitárias (helpers ou padrões como Page Object Model).
  • Mantenha os testes determinísticos: Um teste deve ter uma única responsabilidade e um fluxo linear previsível.
Regra de Ouro: O seu teste deve ser simples a ponto de qualquer pessoa no time entender o que está sendo validado em uma leitura de 10 segundos.

❌ 7. Ignorar a manutenção dos testes

🚨 O problema: Tratar os scripts de automação como "código pronto e esquecido". Conforme o sistema evolui, a falta de manutenção transforma a suíte de testes em um gerador contínuo de falsos negativos (testes que quebram sem que haja um bug real no sistema).

💡 Exemplo prático: A equipe de desenvolvimento altera a estrutura de IDs ou seletores da tela de login para aplicar um novo layout. Como a automação não é atualizada, 15 testes dependentes dessa tela falham no pipeline de CI/CD. Em vez de corrigir os scripts imediatamente, a equipe decide desabilitar os testes ou "deixar para depois", tornando a suíte irrelevante e ignorada pelo time.

✅ Como evitar:

  • Refatore junto com o código da aplicação: Alterações de layout ou regras de negócio devem incluir a atualização dos testes no mesmo ciclo de desenvolvimento (Sprint).
  • Adote seletores resilientes: Utilize atributos dedicados exclusivamente para testes (como data-testid ou data-cy) para evitar que mudanças visuais quebrem a automação.
  • Elimine o código morto: Delete ou refatore cenários obsoletos de funcionalidades que foram descontinuadas ou modificadas.
Regra de Ouro: Um teste automatizado desatualizado é pior do que nenhum teste, pois ele consome tempo da equipe com falsos alarmes e destrói a confiança na automação.

🧠 Conclusão

Automação de testes não é só escrever código — é estratégia.

  • ✔️ Testes mais estáveis
  • ✔️ Menos retrabalho
  • ✔️ Mais confiança

🔗 Continue aprendendo

💡 Dica final: Foque em poucos testes, mas com qualidade.

Se esse conteúdo te ajudou, compartilha com alguém que está aprendendo QA 🚀

Comentários

Postagens mais visitadas deste blog

🚀 O que estudar para ser QA em 2026: guia completo para iniciantes