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

fluxo de TDD com Claude Code para testes automatizados no terminal
Resposta rápida

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
Pré-inscrição Formação Claude Code

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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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

  1. 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.




Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 27min

Blog | Mais populares