Desenvolvimento Orientado a Testes
Construa funcionalidades e corrija bugs uma fatia vertical de cada vez, usando testes como o ciclo de feedback.
Princípio central
Os testes verificam o comportamento por meio de interfaces públicas, não de detalhes de implementação. Se você refatorar e o teste falhar sem que o comportamento mude, o teste estava errado.
Antipadrão: fatias horizontais
Não escreva todos os testes primeiro, depois toda a implementação. Escreva um teste, faça-o passar e repita.
Errado: VERMELHO teste1, teste2, teste3 -> VERDE impl1, impl2, impl3
Certo: VERMELHO teste1 -> VERDE impl1 -> VERMELHO teste2 -> VERDE impl2 -> ...
Fluxo de trabalho
1. Planejar
- Confirme as alterações de interface com o usuário.
- Confirme quais comportamentos testar. Você não pode testar tudo.
- Liste os comportamentos como resultados observáveis, não como etapas de implementação.
- Obtenha aprovação do usuário antes de escrever código.
2. Projétil traçador
Escreva um teste para um comportamento. Observe-o falhar. Escreva o código mínimo para fazê-lo passar.
3. Ciclo incremental
Para cada comportamento restante:
- Escreva o próximo teste.
- Faça-o passar com código mínimo.
- Não antecipe testes futuros.
4. Refatorar
Depois que todos os testes passarem:
- Extraia duplicações.
- Aprofunde módulos: interface pequena, implementação profunda.
- Execute os testes após cada etapa de refatoração.
Nunca refatore enquanto estiver no VERMELHO.
Lista de verificação por ciclo
- O teste descreve o comportamento, não a implementação.
- O teste usa a interface pública.
- O teste sobreviveria a uma refatoração interna.
- O código é mínimo para este teste.
- Nenhuma funcionalidade especulativa adicionada.
Regras
- Escreva testes antes da implementação para novo comportamento.
- Use dicas de tipo e nomes claros.
- Mantenha as funções pequenas e com um único propósito.
- Falhe rapidamente com mensagens de erro claras.