Como usar o Claude Code para escrever testes automatizados no seu projeto

Usar o Claude Code para escrever testes automatizados é rápido, mas teste que passa não é a mesma coisa que teste que protege. O fluxo que a Anthropic recomenda é TDD: você define os casos como pares de entrada e saída esperados, deixa explícito que está fazendo TDD pro agente não criar mock de coisa que ainda não existe, revisa e manda commitar os testes, e só então pede a implementação instruindo a não tocar neles até tudo passar. E no fim exige a evidência: o comando que rodou e a saída real, nunca a afirmação de sucesso
Fala aí, beleza? Peça uma suíte de testes pro agente e em poucos minutos a tela enche de arquivo verdinho, tudo passando, tudo lindo
Aí você quebra a função de propósito pra ver o que acontece
E nada falha 🙃
Esse é o problema real de pedir testes pra IA: o modelo otimiza pra entregar um teste que PASSA, não um teste que falharia se o comportamento estivesse errado. Aqui eu te mostro o passo a passo de como pedir, como revisar antes de aceitar e como consertar o pedido quando vier aquele teste que só confirma a própria implementação
O que você precisa antes de pedir o primeiro teste
Antes de abrir a boca pro agente, três coisas precisam estar de pé
1. Um comportamento existente escolhido, ou os pares de entrada/saída definidos
Ou você aponta pra um pedaço do código que já funciona e quer blindar, ou você chega com os casos esperados na mão: dado isso, deve sair aquilo. Sem esse alvo, o agente vai inventar o alvo sozinho, e é aí que a coisa desanda
2. O runner de teste do projeto rodando por um comando
Se você não consegue rodar a suíte no terminal, o agente também não consegue. Não importa se é o runner do seu ecossistema (JS, Python, PHP, por aí vai): o que importa é existir UM comando que roda e devolve saída
3. O CLAUDE.md com comandos e convenções
O CLAUDE.md guarda as instruções persistentes do projeto e é lido no início de toda sessão. É o lugar dos fatos que o Claude precisa manter em qualquer conversa: comando de build, comando de teste, convenções, layout do projeto e regras do tipo "sempre faça X"
E tem dois sistemas de memória convivendo, não só um: o CLAUDE.md, que é o que VOCÊ escreve, e a memória automática, que são as notas que o próprio Claude escreve a partir das suas correções e preferências. O comando /memory abre essa pasta de notas pra você navegar
Ainda um detalhe de teclado que muda tudo no fluxo: Shift+Tab alterna os modos durante a sessão, no ciclo default → acceptEdits → plan. Guarda esse, porque o passo 1 depende dele
E se você ainda está decidindo o agente do projeto, dá uma olhada na comparação entre Kimi K3 e o Claude Code, porque o critério de teste que eu vou descrever aqui vale do mesmo jeito
Domine o Claude Code do básico ao avançado
Você vai aprender a criar sistemas completos com Claude Code, sem precisar ser programador. Inscreva-se para ter acesso a um desconto de lançamento e bônus especiais!
Passo a passo: pedindo testes ao Claude Code sem aceitar de olhos fechados
A sequência abaixo segue o fluxo de TDD que a Anthropic descreve nas boas práticas do Claude Code, com as paradas de revisão que eu acho que ninguém deveria pular
- Explore o comportamento em plan mode ANTES de pedir código
A orientação da Anthropic é separar pesquisa e planejamento da implementação, pra não resolver o problema errado. O plan mode existe exatamente pra isso: separar exploração de execução. Chega nele com Shift+Tab e peça só leitura e entendimento
Leia o módulo de autenticação e me explique o comportamento atual do login:
quais entradas ele aceita, o que retorna em sucesso e o que retorna em falha.
Não escreva código ainda, só me devolva o entendimento.
O erro comum deste passo: ir direto no "escreve os testes desse arquivo aí". Sem exploração, o agente testa o que ele ACHA que o código faz, e o teste vira retrato do palpite dele
- Defina os casos que importam como pares de entrada e saída esperados
Aqui é você quem trabalha, não o agente. Lista curta, casos que doem: o caminho feliz, o limite, o erro, o valor vazio. O par tem que ser explícito, entrada de um lado e saída esperada do outro
Escreva testes para a função de login com estes casos:
- email válido + senha correta -> sessão criada
- email válido + senha errada -> erro de credencial, sem sessão
- email inexistente -> mesmo erro de credencial (não vaza que o email não existe)
- senha vazia -> erro de validação antes de consultar o banco
O erro comum deste passo: mandar "cobre bem essa função". Cobertura sem caso definido é convite pro agente gerar teste de enfeite
- Diga com todas as letras que é TDD
A Anthropic é explícita nisso: deixe claro que se trata de desenvolvimento guiado por testes, justamente pra ele evitar criar implementações falsas (mock) de funcionalidade que ainda não existe no código
Estamos fazendo TDD. A funcionalidade AINDA NÃO EXISTE.
Escreva os testes primeiro, com base nos pares de entrada/saída acima.
Não crie mock nem implementação falsa da funcionalidade para os testes passarem.
É esperado que eles FALHEM agora.
O erro comum deste passo: omitir o "é TDD". Sem isso o agente vê teste vermelho e o instinto dele é fazer verde do jeito mais fácil, que é mockar a função inteira
- Revise os testes e só ENTÃO mande commitar
Esta é a parada de inspeção que quase todo mundo pula. Lê teste por teste e pergunta uma coisa só: se o comportamento estivesse errado, esse teste falharia? Se a resposta for não, joga fora e reescreve o caso
Depois que estiverem satisfatórios, aí sim manda commitar
O erro comum deste passo: commitar a suíte junto com a implementação lá no fim. Quando os dois entram juntos, você perde a única janela em que dá pra ver o teste sozinho, sem o código que ele deveria estar cobrindo
- Peça a implementação instruindo a NÃO tocar nos testes
Agora sim o código. E a instrução tem que ser dura nesse ponto
Agora escreva o código que faz esses testes passarem.
Não modifique os arquivos de teste.
Continue iterando até que TODOS os testes passem.
O erro comum deste passo: esquecer a trava. Sem ela, quando o código não passa, o caminho mais curto pro agente é ajustar a expectativa do teste até bater. Aí o teste vira espelho da implementação
- Exija evidência, não a afirmação de sucesso
A orientação é sempre fornecer verificação (testes, scripts, capturas de tela) e pedir que o Claude MOSTRE a evidência em vez de dizer que deu certo: a saída do teste, o comando que ele rodou e o que aquilo devolveu
Mostre o comando exato que você rodou e cole a saída completa do runner.
Não me diga que passou, me mostre.
O erro comum deste passo: aceitar o "tudo passando! ✅" do resumo final. Resumo de agente não é saída de runner, e é justamente nessa brecha que suíte verde e app quebrado conseguem conviver sem ninguém perceber
- Commite o código
Fecha o ciclo. Testes num commit, implementação em outro, com a revisão sua no meio dos dois
E se travar? A recomendação da Anthropic é bem direta: depois de DUAS correções falhas, para de insistir no mesmo fio. Usa /clear e escreve um prompt inicial melhor, já incorporando o que você aprendeu nas tentativas. O motivo é prático: a janela de contexto enche rápido e o desempenho cai conforme ela enche
Insistir na terceira correção geralmente é você pagando token pra conversar com um contexto entupido
O teste que só confirma a própria implementação (e como corrigir o pedido)
Esse é o padrão que mais aparece em teste gerado por IA e tem nome: teste tautológico
Ele acontece quando o teste afirma a implementação de volta pra ela mesma, em vez de comparar com um resultado esperado derivado de forma independente. E existe uma razão bem burra pra isso acontecer em escala: o caminho mais fácil de gerar um teste é chamar a própria função pra obter o valor esperado 🙂
Os quatro sintomas que eu procuro na revisão:
| Sintoma | Causa | Como prevenir |
|---|---|---|
| O valor esperado sai de uma chamada da própria função | Teste tautológico: compara a saída com ela mesma | Escrever o esperado à mão, derivado de forma independente da implementação |
| A asserção é sobre o retorno de um mock configurado no mesmo arquivo | Valida o mock, não o comportamento real do código | Testar o comportamento observável, não o valor que você mesmo plantou |
| O teste quebra quando você renomeia uma variável privada | Acoplamento a detalhe interno, não a comportamento | Testar a interface pública: entrada, saída e efeito |
| O teste chama a função e não afirma nada | Execução sem asserção | Todo teste precisa de uma expectativa explícita |
O detalhe cruel: um teste que chama a função e não afirma nada não pega nenhuma linha quebrada, e o teste tautológico também não pega
E mesmo assim os dois marcam 100% de cobertura de linha
Quer dizer: dá pra ter uma suíte verde, com cobertura cheia, que não detecta NENHUMA regressão. A cobertura mediu que a linha foi executada, não que alguém checou o resultado dela
A raiz de tudo é a mesma: a IA otimiza pra produzir um teste que passa, não um teste que falharia se o comportamento estivesse errado. E tem gente alertando com razão pra falsa sensação de segurança de uma suíte gerada por LLM, porque falta ao processo o entendimento de POR QUE aqueles testes funcionam
A correção do pedido é curta e resolve boa parte:
Regras para estes testes:
- o valor esperado deve ser escrito literalmente, nunca obtido chamando a função testada
- não afirme sobre o retorno de mocks configurados neste mesmo arquivo
- teste comportamento observável, não detalhe interno
- todo teste precisa ter pelo menos uma asserção
Depois, quebre a implementação de propósito e me mostre a saída provando
que o teste correspondente FALHA.
Esse último pedido é o melhor filtro que eu conheço: teste que não falha quando deveria falhar não é teste, é decoração
Onde esse fluxo compensa mais
Nem todo projeto pede o ritual completo. Três cenários onde ele paga o próprio custo:
Cobrir comportamento existente antes de refatorar
Aqui o teste é a rede. Você fixa o comportamento atual em pares de entrada e saída, commita, e só depois deixa o agente mexer na estrutura. É a mesma lógica que eu uso pra refatorar um projeto legado sem quebrar tudo: sem alvo verificável, refatoração com IA vira aposta
Feature nova conduzida por TDD
A justificativa da Anthropic pro padrão é que o Claude tem desempenho melhor quando existe um alvo claro pra iterar contra: um mock visual, um caso de teste ou outro tipo de saída esperada. Com o alvo, ele altera, avalia o resultado e melhora até acertar
Sem alvo, ele só… acha que acertou
Revisão de formatação e refatoração de casos de teste
A própria Anthropic relata que o time de Product Design usa o Claude Code pra escrever testes de funcionalidades novas e automatizou comentários de Pull Request via GitHub Actions, com o Claude cuidando de problemas de formatação e refatoração de casos de teste
E o time de Security Engineering relatou algo que provavelmente descreve metade dos projetos por aí: eles trocaram o fluxo "documento de design → código porco → refatoração → desistir dos testes" por pedir pseudocódigo ao Claude e conduzi-lo por desenvolvimento guiado por testes, com checagens periódicas
Repara na parte mais honesta daquele fluxo antigo: desistir dos testes kkk todo mundo já esteve ali
Subagente pra não entupir o contexto
Quando a fase de testes é grande, dá pra jogar esse trabalho num subagente
Subagentes são definidos em arquivos Markdown com frontmatter YAML, salvos em ~/.claude/agents/ (nível de usuário, valem em todos os projetos) ou em .claude/agents/ (nível de projeto, valem só ali e podem ser compartilhados com o time)
O ganho é triplo, segundo a documentação: preservam contexto mantendo exploração e implementação fora da conversa principal, permitem limitar quais ferramentas aquele subagente usa e devolvem apenas o resumo do trabalho feito
Ou seja: a leitura de vinte arquivos acontece longe do seu contexto, e o que volta pra conversa é o resultado
Hook pra verificar depois da edição
Hooks são configurados em .claude/settings.json na raiz do projeto
O evento PostToolUse com o matcher "Edit|Write" roda apenas depois das ferramentas de edição de arquivo, que é exatamente o momento em que você quer disparar uma verificação
Dois detalhes práticos: a partir da versão v2.1.191 a vírgula separa alternativas igual ao pipe, então "Edit, Write" equivale a "Edit|Write". E o comando /hooks, dentro do Claude Code, lista tudo que está configurado agrupado por evento. Se precisar desligar geral, existe o "disableAllHooks": true no arquivo de settings
Como foi na prática rodando um plano com TDD
No vídeo abaixo eu mostro esse fluxo rodando num projeto de exemplo, e vale contar como foi de verdade
Eu parti de um documento de design já aprovado e pedi pra transformar em plano de implementação, com as tarefas em ordem, as dependências e os critérios de aceitação. Só depois disso mandei executar, pedindo explicitamente que rodasse com subagents e com TDD: teste antes, implementação depois
A execução fechou 14 tarefas
E teve tarefa que ficou rodando por quase 10 minutos, então prepara o café ☕
Uma coisa que eu não esperava: a execução com testes gera MUITOS pedidos de aceite na tela. Nessa fase de criação de arquivo, considera usar o modo que pula as confirmações, senão você vira funcionário do Enter
E aqui a parte honesta. No fim, o Claude Code declarou que tinha feito os testes também. Aí eu abri o app no navegador
O cadastro falhou
O login retornou erro
Colei a mensagem de volta na conversa pedindo análise e correção, e só então consegui acessar o app. Ou seja: os testes existiam, passavam, e não pegaram o erro que apareceu no primeiro uso real. É exatamente o ponto da seção anterior aparecendo na minha cara
Eu adapto isso ao tamanho do projeto: em coisa grande, com mais regra de negócio, eu peço TDD pra tentar garantir que a execução já saia testada. Em projeto pequeno, nem sempre compensa. Demora mais e consome mais token, sem dúvida, mas o prompt sai bem mais certeiro
Bala de prata? Longe disso. É o que eu venho testando no dia a dia e funciona pra mim
Ah, e um truque bobo que evita dor de cabeça: referencia o arquivo do plano explicitamente no pedido, em vez de confiar que o contexto da conversa vai lembrar qual é
Próximo passo
O critério de aceite de um teste cabe numa frase
Bom teste é aquele que FALHARIA se o comportamento estivesse errado
Todo o resto (cobertura cheia, suíte verde, resumo bonito no fim da execução) é secundário e pode estar mentindo pra você
Então o próximo passo prático é: escolhe um comportamento que já existe no seu projeto, roda o ciclo hoje mesmo (testes com os pares definidos por você → revisar e commitar → implementação sem tocar nos testes até tudo passar) e depois quebra a função de propósito pra ver o teste falhar
Deu certo? Registra as convenções de teste no CLAUDE.md, que é lido no início de toda sessão, e você não precisa repetir isso nunca mais
Pra mais receitas passo a passo, a documentação oficial tem a página Common workflows, com fluxos de depuração, testes, PRs e outros
Até o próximo post! =)
Perguntas frequentes
Como saber se um teste gerado pelo Claude Code é tautológico?
O sinal é o teste afirmar a implementação de volta para ela mesma, em vez de comparar com um resultado esperado definido de forma independente. Se a asserção vem de um mock configurado no próprio arquivo de teste, ou se o teste quebra só porque você renomeou uma variável privada, ele está validando a implementação, não o comportamento.
Cobertura de 100% significa que os testes pegam qualquer bug?
Não. Um teste que não afirma nada e um teste tautológico que compara a saída da função com ela mesma não pegam nenhuma linha quebrada, e ainda assim os dois marcam cobertura de linha de 100%. Cobertura mede execução, não se o teste detectaria um comportamento errado.
O que fazer quando o Claude Code erra a correção do teste duas vezes seguidas?
A orientação é usar /clear e reescrever o prompt inicial incorporando o que você aprendeu na tentativa anterior. A janela de contexto enche rápido e o desempenho cai conforme ela enche, então insistir corrigindo em cima do mesmo histórico tende a piorar em vez de resolver.
Dá para automatizar a rotina de testes com hooks no Claude Code?
Sim, hooks são configurados em .claude/settings.json na raiz do projeto, e o evento PostToolUse com o matcher Edit|Write roda automaticamente depois que o agente edita ou cria um arquivo. O comando /hooks lista tudo o que está configurado agrupado por evento, e dá para desativar todos de uma vez com "disableAllHooks": true.
Vale criar um subagente só para escrever testes no Claude Code?
Vale, principalmente em projetos grandes. Subagentes ficam em ~/.claude/agents/ (valem em todos os seus projetos) ou em .claude/agents/ dentro do repositório (valem só ali e podem ser compartilhados com o time), e a vantagem é isolar a exploração do código de teste fora da conversa principal, devolvendo só o resumo do trabalho.
A própria Anthropic usa o Claude Code para escrever testes internamente?
Sim. O time de Product Design usa o Claude Code para testes de funcionalidades novas e automatizou comentários de Pull Request via GitHub Actions, enquanto o time de Security Engineering relatou ter trocado um fluxo onde os testes eram abandonados por pedir pseudocódigo ao Claude e conduzi-lo por TDD com checagens periódicas.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
As diferenças de var, let e const
Como fazer redirecionamento com PHP
Neste artigo você vai aprender a como fazer redirecionamento com PHP, utilizaremos abordagens fáceis de entender e de aplicar Fala programador(a), beleza? Bora aprender mais […]
Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação
Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação A popularidade da automação de processos com o n8n está em alta, principalmente […]
