Pular para o conteúdo

Testes e TDD

Testes bem escritos são o principal mecanismo de feedback rápido de um dev. Eles sustentam a confiança para refatorar, documentam intenção executável e revelam problemas de design antes que virem dívida. Este módulo cobre desde os fundamentos da automação até TDD como técnica de design, passando pela taxonomia de dublês de teste e pelo uso crítico de IA na suíte.

O fio condutor é a relação entre testabilidade e arquitetura: código difícil de testar quase sempre é código mal acoplado. A inversão de dependência (DIP) e as fronteiras da Arquitetura Hexagonal existem, entre outras razões, para tornar o teste barato.

Nota O que é
Fundamentos da Automação de Testes Por que automatizar, o que é um bom teste, Arrange-Act-Assert, determinismo, custo x confiança e os limites da cobertura.
Princípio FIRST As cinco propriedades de um bom teste unitário: Fast, Independent, Repeatable, Self-validating, Timely — com violações e correções.
Tipos de Teste - Unit, Integration e E2E A Pirâmide de Testes de Cohn, o anti-padrão do sorvete invertido e quando usar cada camada.
Test-Driven Development O ciclo Red-Green-Refactor, TDD como técnica de design, baby steps e as escolas classicista e mockista.
Test Doubles - Stub, Spy, Mock e Fake A taxonomia de Meszaros e a diferença semântica entre verificação de estado (stub) e de comportamento (mock).
Testes com IA Gerar testes com LLMs, revisar criticamente testes de IA e reforçar a suíte com mutation testing e property-based testing.
graph TD
    A[Fundamentos da Automação de Testes] --> B[Princípio FIRST]
    B --> C[Tipos de Teste - Unit, Integration e E2E]
    C --> D[Test Doubles - Stub, Spy, Mock e Fake]
    D --> E[Test-Driven Development]
    E --> F[Testes com IA]
graph TD
    E2E["E2E - poucos, lentos, caros"] --> INT
    INT["Integração - alguns, banco real via Testcontainers"] --> UNIT
    UNIT["Unitários - muitos, rápidos, isolados"]

Muitos testes na base (rápidos e baratos), poucos no topo (lentos e frágeis). Inverter essa proporção — o sorvete invertido — produz suítes lentas, instáveis e caras de manter. Detalhes em Tipos de Teste - Unit, Integration e E2E.

A dificuldade de escrever um teste é um sinal de projeto. Se você precisa de dez mocks para exercitar um método, o método concentra responsabilidades demais. Se não consegue substituir o banco, faltou uma porta e um adapter. A ligação entre desenho e testabilidade está detalhada em Testabilidade e Arquitetura, e os cheiros que dificultam testes aparecem em Code Smells e SOLID.

Um dublê de teste (um Fake de repositório, por exemplo) é literalmente um adapter alternativo para a mesma porta usada em produção. Essa simetria é o coração da Arquitetura Hexagonal.

Sem uma rede de testes confiável, refatorar é apostar. A suíte é a licença para mudar o código sem medo — o passo Refactor do ciclo TDD só é seguro porque os testes verdes o protegem. A disciplina de melhorar o desenho sem mudar comportamento está em Clean Code e Refactoring.

1. Por que a pirâmide tem muitos testes na base e poucos no topo?

Resposta

Testes unitários são rápidos, baratos e estáveis; servem como feedback de primeira linha e localizam defeitos com precisão. Testes de E2E são lentos, caros e frágeis, mas dão confiança de integração ponta a ponta. A proporção equilibra velocidade de feedback com cobertura de risco real.

2. Qual a relação entre um Fake de teste e a Arquitetura Hexagonal?

Resposta

Um Fake é um adapter de teste que implementa a mesma porta que o adapter de produção. A hexagonal, ao inverter dependências para portas, torna trivial trocar o adapter real por um dublê — testabilidade é uma consequência direta do desenho.

3. Por que o módulo trata TDD como técnica de design e não só de verificação?

Resposta

Escrever o teste antes força a pensar na interface pública e nas dependências como colaborações injetáveis, empurrando o código para baixo acoplamento e conformidade com DIP. O design emerge da necessidade de tornar cada passo testável.

4. Por que os testes são pré-requisito para refatorar com segurança?

Resposta

Refactoring altera a estrutura interna preservando o comportamento observável. Sem testes que fixem esse comportamento, não há como distinguir uma refatoração de uma quebra. A suíte verde é a condição que torna a mudança verificável.