Como fazer o Claude Code rodar os testes em vez de só dizer que funcionou

Fazer o Claude Code rodar testes antes de dizer que terminou não é questão de prompt bonito, é questão de fechar a saída. O CLAUDE.md guarda os comandos exatos de build e de teste, o hook PostToolUse dispara a checagem logo depois de uma edição, o exit code 2 bloqueia a ação e devolve o stderr como feedback pro modelo, e o hook Stop (que é bloqueável) impede o agente de encerrar o turno com teste vermelho. Dá ainda pra empacotar esse loop de verificação como skill e distribuir pro time. Concluído passa a ser teste executado e saída lida, não promessa.
Existe uma frase que todo vibe coder já leu na tela: "pronto, implementei e validei, está tudo funcionando"
Aí você abre o projeto e nada foi executado 🙂
A ideia deste post é trocar a promessa do agente por prova executada, usando o que o próprio Claude Code já oferece: comandos declarados no CLAUDE.md, hooks que disparam a checagem, skills pra empacotar o loop de verificação e o fluxo de TDD que a documentação oficial recomenda
Nada de prompt mágico, beleza? É mecânica mesmo
O buraco na prática: pedi a porta 3000, o servidor subiu na 3005
Esse problema não é teórico, e eu peguei ele ao vivo
Um aviso antes pra ninguém confundir: esse caso NÃO foi no Claude Code
Foi no vídeo em que testo o Pi, um agente minimalista, que é outra ferramenta
Trago ele aqui porque o furo é do mesmo tipo que a gente vai fechar no Claude Code nos passos abaixo: promessa de validação no lugar de comando executado
No prompt de criação do projeto eu já tinha embutido uma verificação executável: rodar o servidor de desenvolvimento e confirmar que abriu na porta 3000
Só que a realidade não obedeceu meu prompt
O servidor subiu na porta 3005, porque as anteriores estavam ocupadas, e eu só descobri isso porque fui LER a saída do terminal
Se eu tivesse aceitado o "confirmei que está rodando", eu teria um número errado na cabeça e uma verificação de mentirinha no bolso
No mesmo vídeo tem um segundo caso, ainda mais clássico
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!
Pedi que o agente criasse uma server action, e junto da resposta ele afirmou por conta própria que tinha feito uma validação da funcionalidade
Não aceitei
Pedi um teste mais manual, e bem concreto: criar uma página de teste que chama a função de buscar commits com um username real do GitHub e renderiza o JSON cru na tela
Depois que o agente criou a página, eu fui até a rota no navegador olhar com os próprios olhos
Aí sim eu sei que funcionou
No vídeo você vê essa sequência inteira: o prompt inicial pedindo leitura, escrita e execução no terminal, o agente pedindo confirmação de entendimento das convenções do projeto antes de gerar código, a porta que não bateu e o teste manual que eu inventei pra não depender da palavra do agente
De novo, pra ficar claro: aquilo ali é o Pi, não o Claude Code
Daqui pra baixo é tudo Claude Code, usando o que ele já traz de fábrica pra transformar "validei" em comando executado
O que você precisa antes de começar
Requisitos curtos, nada de PC da Nasa aqui:
- Claude Code instalado e um projeto com suíte de testes que JÁ roda no terminal (se o teste não roda na sua mão, ele não vai rodar na mão do agente)
- saber o comando exato de teste do projeto, o mesmo que você digitaria:
npm test,pytest,go test ./..., o que for - acesso ao
~/.claude/settings.json(configuração de usuário) ou ao.claude/settings.jsondo projeto, que é onde os hooks moram, com eventos, matchers e comandos
Um aviso que economiza uma tarde inteira de debug: sessões do Claude Code na web NÃO leem o ~/.claude/settings.json local
Nesses casos os hooks vêm do repositório e das configurações gerenciadas pela organização
Ou seja, hook pessoal na sua máquina não acompanha a sessão da web
Passo a passo para o Claude Code provar que o teste passou
A lógica é simples: se o agente pode declarar sucesso sozinho, ele vai declarar
Então a gente tira essa decisão dele e coloca num comando que roda de verdade
- Escreva os comandos exatos de build e de teste no
CLAUDE.md
A documentação oficial de boas práticas recomenda exatamente isso: listar os comandos no CLAUDE.md pra o agente não ter que adivinhar
Parece bobo, mas adivinhação é a origem de metade do problema
## Comandos do projeto
- Instalar: `npm ci`
- Build: `npm run build`
- Testes: `npm test`
- Teste de um arquivo: `npm test -- caminho/do/arquivo`
O erro comum deste passo: escrever "rode os testes" e achar que isso é instrução
Sem o comando literal, o agente inventa um script que não existe, toma erro, e depois te conta que "a suíte não foi necessária" 😛
- Crie o hook
PostToolUsecom matcher por ferramenta
O PostToolUse roda DEPOIS que uma ferramenta é executada, então ele é o gancho certo pra disparar a checagem logo em seguida de uma edição de arquivo
É aqui que o "eu acho que está certo" vira "o comando rodou"
A configuração vive nos arquivos settings.json que citei ali em cima, com o evento, o matcher da ferramenta e o comando de shell que você quer disparar
O erro comum deste passo: pendurar a checagem em QUALQUER ferramenta
Se o hook dispara até quando o agente só leu um arquivo, você transforma uma sessão de trabalho numa suíte de teste em loop, e ninguém merece isso
- Devolva a falha pro modelo com exit code 2
Esse é o pulo do gato
Um hook que sai com código 2 bloqueia a ação, e o texto escrito em stderr volta pro Claude como feedback, pra ele se corrigir
#!/usr/bin/env bash
# .claude/hooks/rodar-testes.sh
saida=$(npm test 2>&1)
status=$?
if [ $status -ne 0 ]; then
echo "Os testes falharam. Saída completa abaixo, corrija antes de continuar:" >&2
echo "$saida" >&2
exit 2
fi
exit 0
Repara no detalhe: eu jogo a SAÍDA do teste no stderr, não um "deu erro" genérico
O modelo precisa do texto do erro pra corrigir, e não de um aviso vago
O erro comum deste passo: montar um JSON caprichado de resposta e sair com código 2
O Claude Code só processa a saída JSON de um hook quando ele termina com código 0
Se sair com 2, o JSON é IGNORADO e vale o stderr
- Feche a saída com o hook
Stop
O Stop dispara quando o agente vai encerrar o turno, e ele é bloqueável
Bloquear o Stop impede o encerramento e faz a conversa continuar
Traduzindo: o agente não consegue dar "tarefa concluída" e sumir enquanto o teste estiver vermelho
É a diferença entre um lembrete e um portão
O erro comum deste passo: confiar só no PostToolUse
O agente pode simplesmente parar de editar arquivos e declarar vitória, e aí nenhum hook de edição vai disparar
- Ajuste o
timeoutconforme a sua suíte
O tempo limite padrão de um hook é de 10 minutos, e dá pra ajustar por hook no campo timeout, informado em segundos
Suíte lenta? sobe o valor
Suíte que às vezes trava esperando input? baixa o valor, pra cortar rápido em vez de deixar a sessão pendurada
O erro comum deste passo: passar minutos onde o campo espera segundos
Colocar 10 achando que são dez minutos te dá dez segundos, e a suíte morre no meio sempre
- Empacote o loop de verificação como skill
Quando o combo começa a funcionar, você vai querer levar ele pra outros projetos
E esse empacotamento tem artigo oficial: a Anthropic publicou o Building verification loops in Claude Code with skills, assinado por Delba de Oliveira, do time do Claude Code
No Claude Code, cada skill é uma pasta com um arquivo SKILL.md como ponto de entrada, configurado por frontmatter YAML seguido do conteúdo em markdown
~/.claude/skills/ # skills pessoais
verificacao/
SKILL.md
.claude/skills/ # skills do projeto
verificacao/
SKILL.md
As skills de projeto são carregadas do diretório onde o Claude Code foi iniciado e dos diretórios pais até a raiz do repositório
E tem uma facilidade MUITO boa aqui: ao adicionar, editar ou remover uma skill nessas pastas, o Claude Code detecta a mudança dentro da sessão atual, sem precisar reiniciar
Dá pra iterar no texto da skill com a sessão aberta e testar na hora
O erro comum deste passo: escrever a skill como um manifesto filosófico sobre qualidade
Skill de verificação boa é chata e concreta: rode ESTE comando, leia a saída, se falhou conserte e rode de novo
- Rode o fluxo de TDD que a documentação recomenda
Hook é o portão, mas TDD é o que dá o que verificar
O fluxo descrito na documentação oficial é o clássico red-green-refactor: escrever um teste que falha com o código atual, implementar a correção e confirmar que o MESMO teste passa sem quebrar o resto
A documentação ainda sugere usar uma sessão do Claude pra escrever os testes e outra pra escrever o código que os faz passar, mantendo os testes independentes
Faz sentido: quem escreve o teste e o código na mesma cabeça tende a ajustar o teste até ele passar 🙂
O erro comum deste passo: deixar o agente "consertar" o teste em vez do código
Se o teste vermelho vira teste verde por edição do arquivo de teste, você não tem prova, tem teatro
Se você está começando agora, vale dar uma olhada também nos erros comuns de quem usa o Claude Code, porque vários deles nascem justamente de aceitar tarefa não executada
Quando a checagem não segura o agente: sintomas e correções
Montou tudo e mesmo assim o agente escapou? se liga na tabela
| Sintoma | Causa provável | Correção |
|---|---|---|
| Hook configurado, nada acontece na sessão web | Sessões do Claude Code na web não leem o settings.json local do usuário |
Mover a configuração pro repositório do projeto ou pras configurações gerenciadas pela organização |
| O JSON que o hook devolve é ignorado | O hook terminou com código 2, e o JSON só é processado no exit 0 | Decidir: ou bloqueia com exit 2 e fala pelo stderr, ou sai com 0 e usa o JSON |
| O agente encerra o turno com teste falhando | Faltou o hook Stop, que é o bloqueável no encerramento |
Adicionar o Stop e bloquear enquanto a checagem não passar |
| A mensagem não aparece pra quem está usando | Falta o campo continue definido como false |
Usar continue: false com o stopReason, que é exibido ao usuário |
| A suíte é cortada no meio | Bateu o tempo limite padrão de 10 minutos | Ajustar o campo timeout do hook, lembrando que o valor é em segundos |
Como prevenir tudo isso de uma vez: teste o hook com um teste que você QUEBROU de propósito
Sério, quebra uma asserção na mão e manda o agente mexer no projeto
Se ele conseguir dizer "concluído" com aquele teste vermelho, o portão não existe, existe decoração
Onde esse loop de verificação compensa mais
Nem todo projeto precisa desse aparato no dia 1, então vale escolher onde ele paga o esforço:
- refatoração ampla, em que o agente toca dezenas de arquivos e ninguém consegue revisar tudo com o olho
- correção de bug com teste de regressão, o caso mais bonito de todos: o teste falha, a correção entra, o mesmo teste passa e ele fica lá pra sempre segurando a regressão
- projeto com suíte rápida, onde rodar a cada edição custa poucos segundos e o feedback volta quente
- padronizar o time, empacotando o loop como skill de projeto dentro de
.claude/skills/pra todo mundo herdar o mesmo portão
Se a distribuição for pra mais de um repositório, plugin resolve
Você adiciona o marketplace e instala:
/plugin marketplace add usuario-ou-org/nome-do-repo
/plugin install <plugin>@<marketplace>
E pra script e automação existem os subcomandos não interativos claude plugin marketplace, equivalentes aos comandos /plugin da sessão interativa
O conceito por trás disso tudo é aquele artigo que citei lá no passo 6
O loop de verificação é definido ali como o ciclo em que o agente checa o próprio trabalho (testes, linters, checagens próprias) e corrige o que falha antes de seguir
É literalmente o que a gente montou nos passos acima, só que com nome de gente grande 😀
Um detalhe prático: suíte rodando a cada edição consome tempo e contexto, então se o seu projeto é grande vale combinar isso com as ideias de fazer o plano render mais e reservar o loop completo pras etapas que realmente importam
Conclusão
A régua muda de lugar aqui, e essa é a parte importante
Concluído não é o agente dizendo que validou
Concluído é teste executado e saída LIDA, do mesmo jeito que eu fui olhar a porta no terminal e a rota no navegador em vez de acreditar no resumo bonitinho
Se você quer um próximo passo prático, faz na ordem: primeiro o CLAUDE.md com os comandos exatos de build e de teste, depois o hook PostToolUse em UM projeto só, e por último o Stop bloqueável
Aí quebra um teste de propósito e vê se o portão segura mesmo o encerramento
Se segurar, você acabou de trocar promessa por prova
até o próximo post!
Perguntas frequentes
Como faço o Claude Code rodar os testes automaticamente depois de cada edição?
Configura um hook no evento PostToolUse, que dispara logo depois que uma ferramenta é executada. Ele mora no settings.json (do usuário ou do projeto) com o matcher da ferramenta e o comando de shell que roda a suíte. É esse hook que troca o "confirmei que está rodando" por um comando executado de verdade.
O hook configurado no settings.json funciona nas sessões do Claude Code pela web?
Não. Sessões do Claude Code na web não leem o ~/.claude/settings.json local, então um hook pessoal na sua máquina simplesmente não acompanha essa sessão. Nesses casos, os hooks vêm do repositório e das configurações gerenciadas pela organização.
Qual a diferença entre o hook PostToolUse e o hook Stop no Claude Code?
PostToolUse dispara depois que uma ferramenta é executada, então é o gancho certo pra checar uma edição de arquivo assim que ela acontece. Já o Stop dispara quando o agente vai encerrar o turno, e ele é bloqueável: bloquear o Stop impede o encerramento e força a conversa a continuar, mesmo que o agente já tenha parado de editar arquivos.
Por que o hook precisa sair com exit code 2 em vez de só devolver um JSON de resposta?
Porque o Claude Code só processa a saída JSON de um hook quando ele termina com código de saída 0. Se o hook sai com código 2, o JSON é ignorado e o que vale é o texto escrito no stderr, que volta pro modelo como feedback pra ele se corrigir.
Dá pra usar o fluxo de TDD (test driven development) com o Claude Code?
Dá, e a documentação oficial descreve esse fluxo: escrever um teste que falha com o código atual, implementar a correção e confirmar que o mesmo teste passa sem quebrar o resto. A própria documentação ainda sugere separar a sessão que escreve o teste da sessão que escreve o código, pra manter os testes independentes.
O que são as skills de verificação do Claude Code e onde elas ficam?
É o formato que a Anthropic descreveu no artigo ‘Building verification loops in Claude Code with skills’, assinado por Delba de Oliveira, do time do Claude Code, o mesmo citado no passo 6 do post: uma skill é uma pasta com um arquivo SKILL.md como ponto de entrada, com frontmatter YAML e o conteúdo em markdown. Skills pessoais ficam em ~/.claude/skills/ e skills de projeto em .claude/skills/, e mudanças nessas pastas são detectadas na sessão em curso, sem precisar reiniciar.
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 […]
ChatGPT: o que é, como usar, dicas e como acessar login
ChatGPT é uma ferramenta de processamento de linguagem natural (NLP) baseada na arquitetura GPT-3.5, desenvolvida pela OpenAI. Sua criação representa um marco significativo no campo […]
