Como aprender TDD do zero — passo a passo
Uma abordagem prática, técnica e direta ao ponto para você dominar o ciclo Red-Green-Refactor desde o início.
1) Fundamentos do TDD: por quê, o que e quando usar
TDD é uma prática que coloca o teste na fronteira do código: você escreve o teste antes de implementar a funcionalidade, guiando o design e assegurando comportamento previsível. O objetivo não é testar tudo de forma exaustiva, mas criar uma faixa de proteção que leva o código a evoluir com controle sobre o risco. Os pilares são:
- Escrever testes que definem o comportamento desejado antes da implementação.
- Executar o ciclo Red-Green-Refactor repetidamente, mantendo a base de código estável.
- Desenhar APIs simples e coesas, com mudanças pequenas, seguras e bem acompanhadas por testes.
Benefícios observáveis incluem melhor design de interfaces, documentação viva do que o código faz e menor acoplamento entre módulos. Evite o extremismo de criar testes demais ou de se agarrar a uma cobertura numérica sem foco no valor do teste.
2) Preparando o ambiente e escolhendo ferramentas
Para começar de forma objetiva, escolha uma stack simples e comum no mercado. Este guia usa JavaScript com Vitest, que oferece uma experiência leve e rápida para TDD. Passos básicos:
- Inicie o projeto e adicione o ambiente de testes:
– npm init -y
– npm i -D vitest - Estruture o repositório:
src/ (código fonte)
tests/ (testes) - Adicione script de testes no package.json:
{ "type": "module", "scripts": { "test": "vitest" } }
Exemplo mínimo de organização de arquivos para o exemplo do método sum:
// Estrutura sugerida
src/sum.js
tests/sum.test.js
3) O ciclo Red-Green-Refactor na prática
Observação prática do ciclo em três passos simples, aplicável a qualquer função pequena. Exemplo: soma de números em um array.
- Escreva um teste que falha (vermelho) — descreva o comportamento esperado sem implementar a função.
- Implemente o código mínimo para fazer o teste passar (verde).
- Refatore o código mantendo os testes verdes, removendo duplicação e melhorando nomes.
Bloco de código relevante (exemplo simplificado com JavaScript/Vitest):
<!-- Arquivo: tests/sum.test.js -->
import { describe, it, expect } from 'vitest';
import { sum } from '../src/sum';
describe('sum', () => {
it('retorna 0 para array vazio', () => {
expect(sum([])).toBe(0);
});
it('retorna a soma de números', () => {
expect(sum([1, 2, 3, 4])).toBe(10);
});
});
<!-- Arquivo: src/sum.js -->
export function sum(arr) {
if (!Array.isArray(arr)) throw new Error('Entrada deve ser array');
return arr.reduce((acc, v) => {
if (typeof v !== 'number') throw new Error('Todos os itens devem ser números');
return acc + v;
}, 0);
}
4) Boas práticas de escrita de testes
- Comece com casos simples que capturem o comportamento essencial da função.
- Nunca deixe testes dependentes de estados globais; mantenha funções puras quando possível.
- Nomeie os testes de forma descritiva: o que está sendo verificado e o resultado esperado.
- Cobertura não substitui qualidade: foque no valor do teste, não apenas no número de casos.
- Crie mocks apenas quando necessário; prefira contratos de entrada/saída estáveis.
Gostou do conteúdo?
Se você curtiu este guia, explore mais posts que ajudam a escrever código limpo com foco em qualidade. Aprenda mais sobre TDD, testes de unidade e padrões de design aplicados a cenários reais.
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!