Projetos práticos para aprender TDD
Guia técnico e prático apresentando ciclos Red-Green-Refactor com atividades reais. Este post corresponde ao tema “projetos-praticos-para-aprender-tdd.md”.
1) Conceito e ciclo do TDD: Red, Green e Refactor
O Test-Driven Development (TDD) orienta o desenvolvimento pela verificação de requisitos por meio de testes, antes da implementação completa. O ciclo padrão é simples e poderoso:
Boas práticas para avançar com TDD:
2) Projeto prático 1: Calculadora de operações básicas com TDD
Objetivo: validar uma API de calculadora com operações simples (adição, subtração, multiplicação, divisão) através de testes antes da implementação completa. O foco é demonstrar o ciclo Red-Green-Refactor com código mínimo e claro.
Plano de teste inicial (Red):
Bloco de código demonstrativo (teste + implementação mínima) — mantém o foco no ciclo TDD:
// tests/calculator.test.js
describe('Calculadora', () => {
it('deve somar dois números', () => {
expect(Calculator.add(2, 3)).toBe(5);
});
it('deve subtrair dois números', () => {
expect(Calculator.sub(5, 2)).toBe(3);
});
it('deve multiplicar dois números', () => {
expect(Calculator.mul(4, 3)).toBe(12);
});
it('deve dividir dois números', () => {
expect(Calculator.div(10, 2)).toBe(5);
});
});
// src/calculator.js (implementação mínima para passar os testes)
export const Calculator = {
add(a, b) { return a + b; },
sub(a, b) { return a - b; },
mul(a, b) { return a * b; },
div(a, b) {
if (b === 0) throw new Error('Divisão por zero');
return a / b;
}
};
Observação: após fazer os testes passarem (Green), reviso o código para refatorar, sem modificar a interface externa. Se desejar, posso detalhar mais casos de borda, como números negativos, frações ou entradas não numéricas, em projetos subsequentes.
3) Projeto prático 2: Gerenciador de tarefas (To-Do) com TDD
Este segundo projeto expande para práticas de modelagem de domínio, gestão de estado simples e validação de regras de negócio. Objetivo: criar um conjunto de testes que guiem a implementação de uma lista de tarefas leve e confiável.
Esboço de código de alto nível (padrões de TDD):
// Testes descritos (pseudo-código)
describe('TaskManager', () => {
it('adiciona uma tarefa com título', () => {
const tm = new TaskManager();
tm.addTask('Estudar TDD');
expect(tm.count()).toBe(1);
});
it('conclui uma tarefa', () => {
const tm = new TaskManager();
tm.addTask('Escrever post');
tm.completeTask(0);
expect(tm.isDone(0)).toBe(true);
});
it('valida título não vazio', () => {
const tm = new TaskManager();
expect(() => tm.addTask('')).toThrow();
});
});
Ideias de implementação para o comportamento mínimo (também em geral, não prescritivo):
4) Projeto prático 3: Cadastro simples com validação de domínio
Neste último módulo, exploramos validação de entradas pela ótica de domínio, definindo regras claras antes de construir a camada de serviço. Objetivo: demostrar como os testes orientam as regras de negócio de forma previsível.
Exemplo de caso de teste em alto nível:
// Testes de validação (alto nível)
describe('UserRegistration', () => {
it('aceita email válido', () => {
expect(isValidEmail('joao@exemplo.com')).toBe(true);
});
it('rejeita senha fraca', () => {
expect(isStrongPassword('1234')).toBe(false);
});
it('rejeita usuário duplicado', () => {
const reg = new UserRegistration();
reg.register('ana', 'ana@example.com', 'Senha123');
expect(() => reg.register('ana', 'ana2@example.com', 'Senha123')).toThrow();
});
});
Notas úteis para este projeto:
- Defina interfaces de domínio simples antes de expor APIs públicas.
- Escreva testes que cubram casos positivos e negativos, assegurando consistência de feedback ao usuário.
- Considere validações em uma camada de serviço, mantendo a validação de regras no domínio puro.
Observação de prática
Os blocos de código acima ilustram a prática de escrever testes antes da implementação completa e de manter o foco na API pública. Adaptar os exemplos para a sua pilha (JS/TS, Python, Java, etc.) é direto: alinhe os nomes das funções aos padrões da sua codebase e ajuste os asserts conforme o framework de testes utilizado.
Gostou? Continue explorando mais conteúdos técnicos
Leve seu conhecimento adiante lendo outros posts do Yurideveloper com foco em qualidade de código, TDD e boas práticas de desenvolvimento.