Testing & TDD
Piramide de testes, xUnit, Moq/NSubstitute, integration tests e padroes de teste em .NET
Testes automatizados sao a rede de seguranca do codigo. TDD (Test-Driven Development) inverte o fluxo: primeiro escreva o teste que falha, depois implemente o minimo para passar, e refatore. O ciclo Red-Green-Refactor garante que cada linha de producao existe por um motivo β satisfazer um teste.
Piramide de Testes
A piramide representa a proporcao ideal de testes por tipo. A base larga indica que unit tests devem ser a maioria β sao rapidos, baratos e isolados. Quanto mais alto na piramide, mais lento, mais caro e mais fragil.
Tipos de Teste
| Tipo | Escopo | Velocidade | Isolamento | Quantidade |
|---|---|---|---|---|
| Unit | Uma classe/metodo isolado | Milissegundos | Total (mocks para dependencias) | Maioria (~70%) |
| Integration | Multiplos componentes juntos | Segundos | Parcial (DB real, HTTP real) | Moderada (~20%) |
| E2E | Sistema completo, ponta a ponta | Minutos | Nenhum (ambiente real) | Poucos (~10%) |
TDD β Red-Green-Refactor
| Fase | Acao | Objetivo |
|---|---|---|
| Red | Escreva um teste que falha | Definir o comportamento esperado antes de implementar |
| Green | Escreva o minimo de codigo para passar | Satisfazer o teste sem over-engineering |
| Refactor | Limpe o codigo sem quebrar testes | Melhorar design mantendo comportamento |
Qual a diferenca entre unit test e integration test?
Unit test isola uma unica unidade (classe/metodo) β todas as dependencias sao substituidas por mocks/stubs. Roda em milissegundos, sem I/O real. Integration test exercita multiplos componentes colaborando β pode usar banco real (Testcontainers/in-memory), HTTP real (WebApplicationFactory) ou filesystem. A fronteira e: se o teste depende de infraestrutura externa, e integration. Se depende apenas de logica in-process, e unit.
O que e o padrao Arrange-Act-Assert (AAA)?
E a estrutura padrao de um teste unitario: Arrange β configure o cenario (crie objetos, configure mocks); Act β execute a acao sendo testada (chame o metodo); Assert β verifique o resultado esperado. Separar claramente essas fases torna o teste legivel e facil de manter. Cada teste deve ter exatamente um Act e assertions relacionadas ao mesmo comportamento.
Convencoes de nomeacao de testes?
A convencao mais comum em .NET e
MethodName_Scenario_ExpectedBehavior. Exemplo: Withdraw_InsufficientFunds_ThrowsInvalidOperationException. Outra abordagem e Should_ExpectedBehavior_When_Condition. O importante e que o nome do teste descreva completamente o cenario sem precisar ler o corpo. Use nomes longos e descritivos β testes nao sao chamados em codigo de producao. Quando usar mock vs dependencia real?
Use mock quando: a dependencia e lenta (HTTP, DB), nao-deterministica (clock, random), ou voce precisa verificar interacoes (foi chamado? com quais parametros?). Use real quando: e um value object puro, uma colecao in-memory, ou em integration tests onde voce quer testar a colaboracao real entre componentes. A regra: mock na fronteira do sistema (I/O, infra), real para logica de dominio.