Desenvolvimento Orientado por Testes (TDD)
TDD é o ciclo vermelho → verde. Esta skill é a referência que faz esse ciclo produzir testes que valem a pena manter: o que é um bom teste, onde os testes vão, os anti-padrões e as regras do ciclo. Cada seção se aplica em cada ciclo: consulte-as antes e durante o ciclo, não depois.
Ao explorar a base de código, leia CONTEXT.md (se existir) para que os nomes dos testes e o vocabulário da interface correspondam à linguagem de domínio do projeto, e respeite as ADRs na área que você está tocando.
O que é um bom teste
Testes verificam comportamento por meio de interfaces públicas, não detalhes de implementação. O código pode mudar completamente; os testes não deveriam. Um bom teste se lê como uma especificação: "o usuário pode finalizar a compra com um carrinho válido" diz exatamente qual capacidade existe, e sobrevive a refatorações porque não se importa com a estrutura interna.
Veja tests.md para exemplos e mocking.md para diretrizes sobre mocks.
Juntas (Seams): onde os testes vão
Uma junta é o limite público onde você testa: a interface onde você observa o comportamento sem acessar o interior. Os testes ficam nas juntas, nunca contra partes internas.
Teste apenas em juntas pré-acordadas. Antes de escrever qualquer teste, anote as juntas sob teste e confirme-as com o usuário. Nenhum teste é escrito em uma junta não confirmada. Você não pode testar tudo, então concordar com as juntas antecipadamente é como o esforço de teste recai sobre os caminhos críticos e a lógica complexa, em vez de cada caso extremo.
Pergunte: "Qual é a interface pública e quais juntas devemos testar?"
Quando o formato dessa interface estiver em questão (quão profundo é o módulo, onde a junta pertence, o que a interface deve expor), chame a ferramenta Skill com "codebase-design" para obter o vocabulário. Ela é a fonte compartilhada dos termos módulo, interface, profundidade, junta, adaptador, alavancagem e localidade, e é uma referência a ser consultada, não uma sessão a ser executada.
Anti-padrões
- Acoplado à implementação: faz mock de colaboradores internos, testa métodos privados ou verifica por meio de um canal lateral (consultando o banco de dados em vez de usar a interface). O sinal: o teste quebra quando você refatora, mas o comportamento não mudou.
- Tautológico: a asserção recalcula o valor esperado da mesma forma que o código faz (
expect(add(a, b)).toBe(a + b), um snapshot derivado manualmente da mesma forma, uma constante afirmada igual a si mesma), então ele passa por construção e nunca pode discordar do código. Os valores esperados devem vir de uma fonte independente de verdade: um literal conhecido como correto, um exemplo trabalhado, a especificação. - Fatia horizontal: escrever todos os testes primeiro, depois toda a implementação. Testes em massa verificam comportamento imaginado: você testa o formato das coisas em vez do comportamento voltado ao usuário, os testes ficam insensíveis a mudanças reais e você se compromete com a estrutura de teste antes de entender a implementação. Trabalhe em fatias verticais: um teste → uma implementação → repita, cada teste uma bala traçadora que responde ao que o último ciclo ensinou.
Regras do ciclo
- Vermelho antes do verde. Escreva o teste que falha primeiro, depois apenas código suficiente para passá-lo. Não antecipe testes futuros nem adicione recursos especulativos.
- Uma fatia de cada vez. Uma junta, um teste, uma implementação mínima por ciclo.
- Refatoração não faz parte do ciclo. Ela pertence ao estágio de revisão (veja a skill
matt-code-review), não ao ciclo de implementação vermelho → verde.