TDD começa antes do código. Ao escrever um teste primeiro, você define como um componente será usado antes de decidir como ele funcionará. Essa ordem torna a interface mais clara e pode levar a uma arquitetura com menos acoplamento.
TDD começa pela interface
Quando o teste vem antes da implementação, a pergunta inicial deixa de ser como construir a classe. Passa a ser como outro componente usará o comportamento.
Essa mudança obriga o código a apresentar uma interface que faça sentido para quem chama. No artigo Test Driven Development , Martin Fowler relaciona esse processo à separação entre interface e implementação. A arquitetura começa a responder ao uso esperado, e não aos detalhes internos escolhidos primeiro.
O teste expõe o acoplamento
O desenho aparece com mais clareza quando o teste exige dependências demais. Se testar uma regra de negócio exige banco, cliente HTTP, relógio do sistema e configurações de ambiente, o teste revela que a regra conhece responsabilidades externas.
O próximo passo é separar a decisão da infraestrutura. A regra recebe dados e devolve um resultado. Outra parte busca dados, chama serviços ou grava mudanças. O teste não prova sozinho que essa divisão é correta, mas mostra o contrato necessário para exercitar a regra.
Esse é o ponto em que TDD afeta a arquitetura. O teste deixa de ser apenas uma verificação posterior e passa a influenciar limites, dependências e responsabilidades.
Um exemplo prático de decisão
Considere uma função que calcula o total de um pedido. O exemplo abaixo é uma simulação. Premissas: o subtotal e o frete são valores fornecidos ao componente, e o total é a soma desses valores.
it('calcula o total do pedido', () => { const pedido = { subtotal: 100, frete: 20 }; expect(totalDoPedido(pedido)).toBe(120); }); O teste já fixa uma interface: o componente recebe um pedido e devolve seu total. Se a implementação precisar abrir uma conexão ou chamar uma API para fazer essa soma, o desenho colocou uma dependência desnecessária na regra.
O teste aponta uma alternativa mais simples para esse caso: deixar o cálculo isolado e entregar os dados prontos para ele. A decisão não vem de uma preferência estética. Ela nasce do comportamento que o componente precisa oferecer.
Como aplicar TDD com critério
O teste precisa dizer qual comportamento o sistema deve manter. A documentação da Microsoft descreve testes escritos antes do código como documentação de design e especificações funcionais. Por isso, nomes claros e entradas relevantes valem mais que uma coleção extensa de casos difíceis de interpretar.
Use o ciclo para revisar o desenho:
- Escreva o comportamento em uma frase que o chamador reconheça.
- Defina a menor interface capaz de expressar esse comportamento.
- Leia a preparação do teste. Dependências que não pertencem à regra indicam uma fronteira mal definida.
- Depois de fazer o código passar, remova a complexidade que o contrato não exige.
O estudo Does Test-Driven Development Really Improve Software Design Quality? formula e investiga empiricamente se TDD produz código mais simples, coeso e menos acoplado do que uma abordagem em que o teste vem depois. Essa investigação não autoriza prometer a mesma qualidade em qualquer projeto. Ela reforça a pergunta que cada equipe precisa fazer: o teste está ajudando a escolher limites melhores ou apenas cobrindo código já difícil?
Próximo passo: escolha um fluxo do seu sistema que acumula retrabalho ou depende de muitas partes externas. Escreva o comportamento esperado antes de alterar a implementação. Se o teste ficar difícil de montar, use essa dificuldade para discutir a arquitetura. A LYPES pode conversar com sua equipe sobre o gargalo e sobre a forma mais adequada de priorizar a evolução do produto.