Douglas ’ Blog

TDD é superestimado

~ 19 de fev. de 2024 ~


Teste de software é uma prática vital no desenvolvimento de software. Sem ele, alterar ou consertar software torna-se um pesadelo.

Mas existem alguns conceitos que não considero úteis na prática do dia a dia.

No meu primeiro post, escrevi que você deveria ignorar Dublês de Test e TDD. Vou explicar o porquê. Além disso, aproveitarei para falar sobre outros conceitos relacionados a testes.

Ignore Dublês de Teste

Primeiro, o que são Dublês de Teste?

Dublê de Teste é um termo genérico para qualquer caso em que você substitui um objeto de produção para fins de teste.

Existem cinco tipos diferentes de Dublê de Teste. Mas, na prática, você só precisa de um stub, um resultado fixo, para tornar seu teste confiável. Dessa forma, o teste não dependerá do banco de dados, aleatoriedade, horário atual, solicitações de rede, etc.

Vamos um por um.

Dummy são repassados, mas nunca são realmente usados. Geralmente eles são usados apenas para preencher listas de parâmetros.

Parece que é apenas um design de assinatura de função ruim.

Fake na verdade têm implementações funcionais, mas geralmente usam algum atalho que os torna inadequados para produção (um InMemoryTestDatabase é um bom exemplo).

Uma abordagem melhor é fazer um teste de integração. Caso contrário, você estará apenas testando a implementação do InMemoryTestDatabase.

Spies são stubs que também registram algumas informações com base em como foram chamados. Uma forma disso pode ser um serviço de e-mail que registre quantas mensagens foram enviadas.

Não sei por que isso seria útil. Mas, do meu ponto de vista, isso também é melhor como teste de integração.

Mocks são pré-programados com expectativas que formam uma especificação das chamadas que devem receber. Eles podem lançar uma exceção se receberem uma chamada inesperada e forem verificados durante a verificação para garantir que receberam todas as chamadas que esperavam.

Mocks são semelhantes a Fakes, mas muito piores, pois possuem mais código específico para o teste. Basta fazer um teste de integração.

Ignore a pirâmide de teste

O que é a pirâmide de teste?

A pirâmide de testes é uma forma de pensar sobre como diferentes tipos de testes automatizados devem ser usados para criar um portfólio equilibrado. Seu ponto essencial é que você deve ter muito mais UnitTests de baixo nível do que BroadStackTests de alto nível rodando através de uma GUI.

Minha primeira reclamação é que a separação de cada camada não é clara. Por exemplo, como você define o que é uma unidade ou integração?

Além disso, testes de unidade excessivos levam tempo e, se o código não for mais necessário, os testes não serão mais necessários.

Geralmente discordo que os testes E2E sejam caros para escrever e executar. Os testes E2E geralmente devem ser rápidos e você também pode selecionar quais testes serão executados. Mesmo os testes unitários podem ser lentos se houver muitos deles. Quando chegar a hora, você otimiza.

O que custa caro é não ter um bom conjunto de testes.

Meu conselho geral é focar em escrever testes para grandes porções do código, o que proporcionará muita confiança. Também deixarei este comentário do Reddit como conselho.

Ignore 100% de cobertura

Você pode alcançar 100% de cobertura. Às vezes, a ferramenta pode contar algum código que não é relevante. Portanto, você pode configurar com segurança para ignorar isso. Além disso, provavelmente uma cobertura de teste mais alta tem retornos decrescentes, portanto, tome cuidado para não ficar obcecado com 100% de cobertura.

Ignore “Uma afirmação por teste”

O livro “xUnit Test Patterns: Refactoring Test Code” descreve um anti pattern de comportamento de teste: Assertion Roulette.

É difícil dizer qual das diversas afirmações dentro do mesmo método de teste causou uma falha no teste.

Portanto, a solução é escrever apenas uma afirmação por teste. Este conselho também aparece no livro Código Limpo.

Não sei por que eles deram esse conselho, mas hoje em dia, a ferramenta de teste pode gerar a linha exata da afirmação que falhou.

Meu conselho: escreva quantas afirmações você precisar, somente se elas estiverem relacionadas ao que você está testando.

Ignore F.I.R.S.T.

Esta sigla vem do livro Clean Code, que pode ser resumido da seguinte forma:

Os testes devem ser executados em paralelo, ser rápidos, determinísticos e cobrir todos os caminhos.

Ignore TDD

Os benefícios que alguns desenvolvedores afirmam sobre o TDD não são exclusivos do TDD. Fazer testes depois tem os mesmos benefícios. É apenas uma questão de estilo. O único problema é não escrever testes.

Existem alguns cenários em que o uso do TDD não é possível, especialmente se você ainda está descobrindo qual deveria ser o código.

Conclusão

Sempre se lembre:

Software sem testes não pode ser mantido.