Embora eu seja totalmente a favor do teste de unidade, às vezes me pergunto se essa forma de desenvolvimento do teste primeiro é realmente benéfica ...
Testes pequenos e triviais como este podem ser o "canário na mina de carvão" para sua base de código, alertando sobre o perigo antes que seja tarde demais. É útil manter os testes triviais porque ajudam a obter as interações certas.
Por exemplo, pense em um teste trivial colocado em prática para investigar como usar uma API com a qual você não está familiarizado. Se esse teste for relevante para o que você está fazendo no código que usa a API "de verdade", é útil mantê-lo por perto. Quando a API lança uma nova versão e você precisa fazer upgrade. Agora você tem suas suposições sobre como espera que a API se comporte, gravadas em um formato executável que pode ser usado para capturar regressões.
... [N] um processo real, você tem 3-4 camadas acima de seu código (Solicitação de Negócios, Documento de Requisitos, Documento de Arquitetura), onde a regra de negócios real definida (Preço com Desconto é Preço - Desconto) pode estar mal definida. Se for essa a situação, seu teste de unidade não significa nada para você.
Se você já codifica há anos sem escrever testes, pode não ser imediatamente óbvio para você que existe algum valor. Mas se você acha que a melhor maneira de trabalhar é "lançar mais cedo, lançar com frequência" ou "ágil" no sentido de que deseja implementar rapidamente / continuamente, então seu teste definitivamente significa algo. A única maneira de fazer isso é legitimar todas as alterações feitas no código com um teste. Não importa o quão pequeno seja o teste, uma vez que você tenha um conjunto de testes verde, você está teoricamente bem para implantar. Veja também "produção contínua" e "beta perpétuo".
Você não precisa ser o "primeiro a testar" para ter essa mentalidade, mas geralmente essa é a maneira mais eficiente de chegar lá. Quando você faz TDD, você se trava em um pequeno ciclo Red Green Refactor de dois a três minutos. Em nenhum momento você não será capaz de parar e sair e ter uma bagunça completa em suas mãos que levará uma hora para depurar e consertar.
Além disso, seu teste de unidade é outro ponto de falha ...
Um teste bem-sucedido é aquele que demonstra uma falha no sistema. Um teste com falha irá alertá-lo sobre um erro na lógica do teste ou na lógica do seu sistema. O objetivo de seus testes é quebrar seu código ou provar que um cenário funciona.
Se você está escrevendo testes após o código, corre o risco de escrever um teste que é "ruim" porque, para ver se seu teste realmente funciona, você precisa vê-lo quebrado e funcionando. Quando você está escrevendo testes após o código, isso significa que você deve "desencadear a armadilha" e introduzir um bug no código para ver o teste falhar. A maioria dos desenvolvedores não está apenas preocupada com isso, mas argumentaria que é uma perda de tempo.
O que ganhamos aqui?
Definitivamente, há uma vantagem em fazer as coisas dessa maneira. Michael Feathers define "código legado" como "código não testado". Ao adotar essa abordagem, você legitima todas as alterações feitas em sua base de código. É mais rigoroso do que não usar testes, mas quando se trata de manter uma grande base de código, ele se paga.
Por falar em penas, existem dois excelentes recursos que você deve verificar a respeito disso:
Ambos explicam como trabalhar esses tipos de práticas e disciplinas em projetos que não são "greenfield". Eles fornecem técnicas para escrever testes em torno de componentes fortemente acoplados, dependências com fio e coisas sobre as quais você não tem necessariamente controle. É tudo uma questão de encontrar "costuras" e testar em torno delas.
[I] se o preço com desconto estiver errado, a equipe de teste ainda encontrará o problema, como o teste de unidade salvou algum trabalho?
Hábitos como esses são como um investimento. Os retornos não são imediatos; eles se acumulam com o tempo. A alternativa para não testar é essencialmente assumir a dívida de não ser capaz de capturar regressões, introduzir código sem medo de erros de integração ou conduzir decisões de design. A beleza é que você legitima todas as alterações introduzidas em sua base de código.
O que estou perdendo aqui? Por favor, me ensine a amar o TDD, pois estou tendo dificuldade em aceitá-lo como útil até agora. Eu também quero, porque quero continuar progressista, mas simplesmente não faz sentido para mim.
Eu vejo isso como uma responsabilidade profissional. É um ideal pelo qual se empenhar. Mas é muito difícil de seguir e tedioso. Se você se preocupa com isso e acha que não deve produzir código que não seja testado, poderá encontrar a força de vontade para aprender bons hábitos de teste. Uma coisa que eu faço muito agora (assim como outros) é um tempo de uma hora para escrever código sem nenhum teste e, em seguida, ter a disciplina de jogá-lo fora. Isso pode parecer um desperdício, mas não é realmente. Não é como se o exercício custasse materiais físicos à empresa. Isso me ajudou a entender o problema e como escrever código de forma que seja de melhor qualidade e testável.
Em última análise, meu conselho seria que, se você realmente não deseja ser bom nisso, não o faça de forma alguma. Testes ruins que não são mantidos, não funcionam bem etc. podem ser piores do que não ter nenhum teste. É difícil aprender sozinho, e você provavelmente não vai adorar, mas será quase impossível aprender se você não tiver o desejo de fazê-lo ou não puder ver o valor suficiente para garante o investimento de tempo.
Algumas pessoas sempre mencionaram que os testes ajudam a fazer cumprir as especificações. Minha experiência mostra que a especificação também está errada, na maioria das vezes ...
O teclado do desenvolvedor é onde a borracha encontra a estrada. Se a especificação estiver errada e você não levantar a bandeira sobre ela, é altamente provável que você seja culpado por isso. Ou pelo menos seu código vai. A disciplina e o rigor envolvidos no teste são difíceis de aderir. Não é nada fácil. É preciso prática, muito aprendizado e muitos erros. Mas eventualmente vale a pena. Em um projeto acelerado e em constante mudança, é a única maneira de você dormir à noite, não importa se isso atrapalhe.
Outra coisa a se pensar aqui é que as técnicas que são fundamentalmente iguais aos testes já provaram funcionar no passado: "sala limpa" e "projeto por contrato" tendem a produzir os mesmos tipos de construções de "meta" código que os testes fazem e os aplicam em diferentes pontos. Nenhuma dessas técnicas é bala de prata, e o rigor vai custar caro no que se refere aos recursos que você pode oferecer em termos de tempo de lançamento no mercado. Mas não é disso que se trata. É sobre ser capaz de manter o que você entrega. E isso é muito importante para a maioria dos projetos.