TDD com IA: por que deixar a IA escrever o teste e o código ao mesmo tempo quebra a verificação?

ciclo Red Green Refactor no TDD com IA, com teste separado do código gerado
Resposta rápida

TDD com IA funciona, mas quebra num ponto específico: quando a mesma conversa escreve o teste e o código, o teste deixa de ser verificação e vira espelho do que a IA acabou de gerar. O ciclo Red, Green, Refactor existe justamente pra provar que o teste detecta a ausência do comportamento, e é o Red que a gente pula quando pede tudo de uma vez. A saída é separar os papéis: descrever o comportamento esperado, pedir o teste sem implementação, ver falhar, e só então pedir o código que passa sem tocar nos testes

Quando a mesma IA escreve o teste e o código na mesma conversa, o teste para de ser verificação e vira espelho

Se liga nisso: tu pede uma feature, a IA gera a implementação, tu completa com um "e escreve os testes também", tudo fica verde de primeira e bate aquela sensação de dever cumprido

Só que o teste não conferiu nada

Ele foi escrito olhando pro código que já estava ali, então ele descreve o que o código FAZ, não o que o código DEVERIA fazer

Se o código nasceu com bug, o teste nasce certificando o bug

Esse post é sobre essa armadilha e sobre como separar os dois papéis na conversa, usando o que a documentação e os estudos já sustentam…

O que o TDD garante e por que a ordem importa

TDD foi criado (ou, nas palavras do próprio autor, redescoberto) por Kent Beck no fim dos anos 1990, dentro do Extreme Programming, e virou livro em 2003 com o Test Driven Development: By Example

O ciclo é aquele que todo mundo já viu: Red, Green, Refactor

Escreve o teste que falha, faz passar, refatora

Agora a parte que quase todo mundo trata como formalidade chata: o Red

O valor do TDD não está em ter teste

Está em ter um teste que FALHOU antes do código existir

O Red é a única prova de que aquele teste consegue enxergar a ausência do comportamento

Teste que nunca falhou é teste não testado, e um teste não testado é só código extra rodando na sua pipeline

É tipo alarme de incêndio: se tu nunca apertou o botão de teste, tu não tem alarme, tu tem uma caixinha branca no teto 😀

Formação Agentes de IA
Formação Recomendada

Formação Agentes de IA

Domine a criação de Agentes de IA e Venda para Empresas

  • 402 aulas
  • 32 projetos
  • 38h 19min

O teste que nasceu do código: como identificar e como evitar

Os sintomas

Dá pra reconhecer esse tipo de teste sem ler linha por linha:

  • ficou verde de primeira, sem nunca ter passado pelo vermelho
  • as asserções são genéricas, do tipo "não é nulo", "tem alguma coisa aqui"
  • aparece print revelando valor no lugar de asserção formal
  • cobre exatamente o caminho feliz que o código já implementa, e só ele
  • toda borda que o código não tratou também não aparece no teste

Repara no padrão: o teste tem exatamente o mesmo campo de visão do código

Não é coincidência, é herança

A causa: o código bugado no contexto contamina o teste

Tem nome pra isso na literatura: efeito de desorientação (misguidance effect)

O artigo Evaluating and Mitigating the Misguidance Effect of Buggy Code in LLM-Generated Unit Tests, de Junda Zhao, Shurui Zhou e Eldan Cohen, aceito na ISSTA 2026, mede justamente isso: quando o LLM recebe o código bugado dentro do prompt, ele passa a gerar mais testes que afirmam o comportamento ERRADO como se fosse o correto, e gera menos testes capazes de encontrar o bug

Ou seja, o problema não é a IA ser ruim de teste

O problema é ela ser boa demais em concordar com o que está na tela

O código vira a especificação, e a especificação de verdade (o que o negócio pede) nunca entrou na conversa

Como evitar

A mitigação que o próprio paper propõe é direta: gerar o teste a partir de uma especificação de comportamento, não do código

Na prática isso significa que a ordem do seu prompt é a sua metodologia agora

Se o código entra no contexto antes do teste, tu já perdeu a independência da verificação, não importa quantos testes vierem depois

Teste humano x teste de agente: o que os estudos mediram

Um estudo empírico comparou testes escritos por humanos e por agentes de IA em projetos open source, analisando 204.673 artefatos de teste (24.941 de humanos e 179.732 de agente, do dataset AIDev)

Métrica Humano Agente de IA
Asserções fortes 88,1% 85,37%
Asserções ambíguas ou não classificadas 1,46% 11,58%
Variedade de checagem de borda 0,32 0,62
Teste de null-safety 8,3% 13,40%

Olha que interessante: em asserção forte o agente empata quase redondo, e em borda e null-safety ele até faz MAIS que o humano

O buraco está numa linha só: asserção ambígua ou não classificada, 1,46% contra 11,58%

É ali que a verificação vaza

Outro estudo, aceito na MSR 2026 (pesquisa do Nara Institute of Science and Technology com a University of Groningen), mediu que agentes de IA assinaram 16,4% de todos os commits que adicionam teste nos projetos estudados

Os testes de IA aparecem mais densos em asserções e com cobertura comparável, mas com risco do smell Assertion Roulette (aquele teste com um monte de asserção sem mensagem, que quando quebra tu não sabe qual delas quebrou)

E tem um terceiro, sobre trajetórias de agentes no SWE-bench Verified, com 6 LLMs analisados: agentes que resolvem o bug escrevem testes praticamente na mesma taxa dos que falham

Experimentos controlados aumentando ou diminuindo a escrita de testes não produziram mudança estatisticamente significativa na taxa de resolução

E os agentes favorecem prints reveladores de valor em vez de asserções formais

A leitura honesta dos três é essa: não é que "IA testa mal"

IA testa DIFERENTE

Volume de teste gerado não compra correção, e ambiguidade de asserção é onde a garantia evapora

Como separar os dois papéis na conversa com a IA

A documentação oficial do Claude Code trata TDD como workflow recomendado e descreve o fluxo com uma ordem bem específica

Ela instrui a pedir os testes a partir de pares entrada/saída esperados, rodar e confirmar que FALHAM, dizer explicitamente ao Claude para NÃO escrever implementação nessa etapa, e só depois pedir o código que passa sem modificar os testes

Bora ver na prática?

  1. Descreva o comportamento em pares entrada/saída, sem mostrar implementação

Nada de colar o arquivo bugado antes

A especificação vem primeiro, sozinha:

Comportamento esperado da funcao aplicarDesconto(valor, cupom):
- (100, "OFF10") -> 90
- (100, "INVALIDO") -> erro de cupom invalido
- (0, "OFF10") -> 0
- (100, null) -> 100

O erro comum deste passo: colar o código junto "pra ela entender melhor o contexto"

É exatamente esse gesto que dispara o efeito de desorientação

  1. Peça os testes e proíba a implementação nessa etapa, com todas as letras
Escreva SOMENTE os testes para o comportamento acima.
Nao escreva nenhuma implementacao nesta etapa.
Nao crie stub, mock da funcao nem arquivo de codigo de producao.

O erro comum deste passo: deixar a proibição implícita

Se tu não fala, ela ajuda, e ajudar aqui significa criar a implementação junto e matar o Red

  1. Rode os testes e confirme que eles FALHAM

Esse passo é inegociável

Teste que passa antes do código existir está testando outra coisa (ou nada)

O erro comum deste passo, e é o mais grave de todos: pular o Red porque "já deu pra ver que tá certo"

Sem o vermelho, tu não tem TDD, tu tem código com anexo

  1. Só então peça o código que passa, sem modificar os testes
Agora implemente o codigo que faz esses testes passarem.
Nao altere nenhum arquivo de teste.

O erro comum deste passo: aceitar teste "ajustado" no meio do caminho

Quando a IA mexe no teste pra fazer passar, o placar continua verde e a verificação já morreu

  1. Use o plan mode pra especificar sem tocar em arquivo

O Claude Code tem modo de planejamento em que ele lê, analisa e propõe um plano sem editar arquivos de código

O Shift+Tab cicla entre os modos Default, Auto-accept edits e Plan mode, e em plan mode as edições ficam bloqueadas até tu aprovar o plano

Dá pra desenhar a especificação inteira ali, com a mão dele amarrada

O erro comum deste passo: sair do plan mode antes de fechar a especificação, e aí o primeiro arquivo criado já é o de implementação

  1. Ponha quem escreve o teste em outro contexto

O Claude Code suporta subagentes com contexto próprio, gerenciados pelo comando /agents, definidos em arquivos Markdown com frontmatter YAML

Os de projeto ficam em .claude/agents/ e os de usuário em ~/.claude/agents/, com name e description obrigatórios no frontmatter

A ideia é simples: quem escreve o teste não deveria ser quem acabou de escrever o código, porque o código na janela é justamente o contaminante

É o mesmo raciocínio de quando tu abre duas sessões no mesmo projeto ou precisa manter dois projetos sem misturar contexto: contexto separado não é frescura, é o que garante que a segunda opinião seja de fato uma segunda opinião

O erro comum deste passo: criar o subagente e mesmo assim colar a implementação no prompt dele

Aí tu só trocou o crachá, o contaminante entrou igual

  1. Transforme a regra do prompt em permissão de verdade

Até aqui tudo depende de tu pedir bonitinho, e pedido não é limite

As permissões do Claude Code no settings.json têm regras allow, ask e deny, avaliadas nessa ordem de precedência

O deny vem primeiro e prevalece sobre um allow, e a primeira correspondência decide

Dá pra usar isso pra tornar a proibição do passo 2 e a do passo 4 uma barreira concreta, não um pedido educado no meio da conversa

O erro comum deste passo: confiar só na instrução em linguagem natural

Instrução é intenção, permissão é limite

  1. Rode os testes automaticamente depois de cada edição

Lembra que o passo 3 é inegociável? Então, dá pra tirar ele da tua memória e botar na máquina

O Claude Code tem hooks de ciclo de vida, e o PostToolUse roda depois que uma ferramenta (incluindo as de edição de arquivo) é executada com sucesso

Ele é configurado no settings.json com matcher de ferramenta e pode disparar lint, formatação ou testes

Assim tu não depende do relatório dela sobre o resultado, tu vê o resultado

O erro comum deste passo: aceitar "os testes passaram" como texto na conversa

Saída de execução é prova, frase não é

Quando separar os papéis vale o atrito e quando não vale

Isso tudo custa tempo, e seria desonesto fingir que não

Então vale calibrar

Vale o atrito quando:

  • é regra de negócio com borda, valor zero, null e caso limite (o lugar onde asserção ambígua machuca mais)
  • é correção de bug, que é literalmente o cenário do efeito de desorientação: o código errado está na tela, e é dele que a IA vai tirar a noção de "correto"
  • o código vai ser mantido por outra pessoa, que amanhã vai confiar naquele teste verde sem saber como ele nasceu
  • é caminho crítico: cobrança, permissão, cálculo que vira número na conta de alguém

Não vale quando:

  • é rascunho descartável, daqueles que morrem na mesma tarde
  • é spike exploratório, tu ainda nem sabe qual é o comportamento certo pra especificar
  • é script de uso único, roda uma vez e vai pro lixo

E deixa claro: isso é escolha de RISCO, não de moral

Ninguém é melhor dev por fazer TDD no script que converte um CSV uma vez na vida 🙂

Vale fazer TDD com IA?

Vale, com uma condição: a IA não pode ser juiz e réu na mesma etapa

A evidência sustenta duas coisas bem concretas

Uma, que código bugado no contexto empurra o modelo a gerar teste que confirma o erro e a gerar menos teste capaz de achar o bug (o efeito de desorientação, ISSTA 2026)

Duas, que teste de agente carrega muito mais asserção ambígua ou não classificada, 11,58% contra 1,46% do humano, e que aparece risco de Assertion Roulette

E tem uma coisa que a evidência NÃO sustenta, apesar de soar bem: que mais teste gerado por agente resolve mais bug

No SWE-bench Verified, agentes que resolvem escrevem teste praticamente na mesma taxa dos que falham, e mexer nesse volume pra cima ou pra baixo não mudou a taxa de resolução de forma estatisticamente significativa

Então TDD com IA não é sobre produzir mais teste

É sobre proteger a INDEPENDÊNCIA do teste

O que muda de fato é onde mora a disciplina: ela saiu do editor e foi pra ordem do prompt

Conclusão

O TDD sempre foi sobre ordem, e a IA não mudou isso, ela só deixou muito mais fácil e mais barato quebrar a ordem sem perceber

O teste que sai junto com o código na mesma resposta não é verificação, é autoelogio

Próximo passo concreto, pro próximo bug que tu pegar: escreve o comportamento esperado em pares entrada/saída ANTES de mostrar qualquer código pra IA, pede só o teste, e exige ver o teste falhar

E guarda essa: se o teste passar de primeira, ele é suspeito, não é conquista

até o próximo post! =)

Perguntas frequentes

Dá pra usar o plan mode do Claude Code pra garantir a etapa Red do TDD com IA?

Dá sim. O Claude Code tem um modo de planejamento em que ele lê, analisa e propõe um plano sem editar arquivo nenhum, e o Shift+Tab alterna entre Default, Auto-accept edits e Plan mode. Enquanto tu está em plan mode as edições ficam bloqueadas até aprovar o plano, então dá pra pedir os testes, revisar a proposta e só liberar a implementação depois de confirmar que eles falharam.

Como impedir que o Claude Code escreva a implementação antes do teste falhar?

Além de pedir explicitamente pra IA não implementar nessa etapa, como manda o fluxo oficial de TDD do Claude Code, dá pra reforçar isso nas permissões do settings.json, que é o passo 7 do fluxo do post. As regras allow, ask e deny são avaliadas nessa ordem de precedência, com deny prevalecendo sobre allow e a primeira correspondência decidindo, então uma regra deny transforma o pedido do prompt em barreira de verdade.

Subagentes do Claude Code servem pra separar quem escreve o teste de quem escreve o código?

O Claude Code suporta subagentes com contexto próprio, gerenciados pelo comando /agents e definidos em Markdown com frontmatter YAML (campos obrigatórios name e description), guardados em .claude/agents/ no projeto ou em ~/.claude/agents/ pro usuário. Dá pra montar um subagente focado só em escrever teste a partir da especificação e outro focado só na implementação, cada um com seu próprio contexto na conversa.

Hooks tipo PostToolUse rodam os testes automaticamente depois que a IA edita o código?

Sim, e é o passo 8 do fluxo do post. O Claude Code tem o evento PostToolUse, configurado no settings.json com matcher de ferramenta, que dispara depois que uma ferramenta (incluindo as de edição de arquivo) é executada com sucesso. Dá pra usar esse hook pra rodar lint, formatação ou a suíte de testes automaticamente assim que o código muda, em vez de aceitar "os testes passaram" como texto na conversa.

Teste escrito por agente de IA é pior que teste escrito por humano?

Não é bem pior, é diferente. Um estudo com 204.673 artefatos de teste (24.941 humanos e 179.732 de agente) achou asserção forte em 88,1% dos testes humanos contra 85,37% dos de agente, praticamente empatado, e o agente até supera em variedade de checagem de borda (0,62 contra 0,32) e teste de null-safety (13,40% contra 8,3%). O buraco real está em asserção ambígua ou não classificada: 1,46% no humano contra 11,58% no agente.

Escrever mais testes com IA aumenta a chance de resolver o bug?

Segundo um estudo com 6 LLMs no SWE-bench Verified, não. Agentes que resolvem o bug escrevem testes praticamente na mesma taxa dos que falham, e experimentos controlados aumentando ou diminuindo a escrita de testes não mudaram a taxa de resolução de forma estatisticamente significativa. O próprio estudo notou que os agentes tendem a usar print revelando valor em vez de asserção formal, o que ajuda a entender por que volume de teste sozinho não é garantia de nada.



Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

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