Escrevemos testes para verificar a correção do comportamento de um programa.
Verificar a correção do comportamento de um programa, inspecionando o conteúdo das instruções de saída usando seus olhos, é um processo manual ou, mais especificamente, visual .
Você poderia argumentar que
Se a inspeção visual funcionar , eu verifico se o código faz o que deve ser feito, para esses cenários e, depois de ver que está correto, estamos prontos para prosseguir.
Agora, primeiro, é ótimo que você esteja interessado em saber se o código funciona ou não corretamente. Isso é uma coisa boa. Você está à frente da curva! Infelizmente, há problemas com isso como uma abordagem.
O primeiro problema com a inspeção visual é que você sofreu um grave acidente de soldagem e nunca conseguiu verificar novamente a correção do seu código.
O segundo problema é que o par de olhos usado está fortemente acoplado ao cérebro do dono dos olhos. Se o autor do código também possui os olhos usados no processo de inspeção visual, o processo de verificação da correção depende do conhecimento sobre o programa internalizado no cérebro do inspetor visual.
É difícil para um novo par de olhos entrar e verificar a correção do código simplesmente porque eles não são associados ao cérebro do codificador original. O proprietário do segundo par de olhos terá que conversar com o autor original do código para entender completamente o código em questão. A conversa como meio de compartilhar conhecimento é notoriamente não confiável. Um ponto discutível se o codificador original não estiver disponível para os novos olhos de par. Nesse caso, o novo par de olhos precisa ler o código original.
Ler o código de outras pessoas que não é coberto por testes de unidade é mais difícil do que ler o código que possui testes de unidade associados. Na melhor das hipóteses, ler o código de outras pessoas é um trabalho complicado, na pior das hipóteses, é a tarefa mais incômoda da engenharia de software. Há uma razão pela qual os empregadores, ao anunciar vagas, destacam que um projeto é um greenfield (ou novíssimo). Escrever código do zero é mais fácil do que modificar o código existente e, assim, tornar o trabalho anunciado mais atraente para os funcionários em potencial.
Com o teste de unidade, dividimos o código em suas partes componentes. Para cada componente, organizamos nossa tenda, indicando como o programa deve se comportar . Cada teste de unidade conta uma história de como essa parte do programa deve agir em um cenário específico. Cada teste de unidade é como uma cláusula de um contrato que descreve o que deve acontecer do ponto de vista do código do cliente.
Isso significa que um novo par de olhos possui dois fios de documentação ativa e precisa sobre o código em questão.
Primeiro eles têm o próprio código, a implementação, como o código foi feito ; segundo, eles têm todo o conhecimento que o codificador original descreveu em um conjunto de declarações formais que contam a história de como esse código deve se comportar.
Os testes de unidade capturam e descrevem formalmente o conhecimento que o autor original possuía quando implementou a classe. Eles fornecem uma descrição de como essa classe se comporta quando usada por um cliente.
Você está certo ao questionar a utilidade de fazer isso, porque é possível escrever testes de unidade que são inúteis, não cobrem todo o código em questão, ficam obsoletos ou desatualizados e assim por diante. Como garantir que os testes de unidade não apenas imitem, mas melhorem o processo de um autor experiente e consciente que inspeciona visualmente as instruções de saída de seu código em tempo de execução? Escreva o teste de unidade primeiro e depois o código para fazer esse teste passar. Quando terminar, deixe que os computadores executem os testes, eles são rápidos e são ótimos em realizar tarefas repetitivas, ideais para o trabalho.
Garanta a qualidade do teste, revendo-os sempre que tocar no código que eles testam e executar os testes para cada compilação. Se um teste falhar, corrija-o imediatamente.
Automatizamos o processo de execução de testes para que sejam executados toda vez que fazemos a construção do projeto. Também automatizamos a geração de relatórios de cobertura de código que detalham qual porcentagem de código é coberta e exercida pelos testes. Nós nos esforçamos para obter altas porcentagens. Algumas empresas impedirão que as alterações de código sejam registradas no controle do código-fonte se elas não tiverem testes de unidade suficientes escritos para descrever quaisquer alterações no comportamento do código. Normalmente, um segundo par de olhos revisará as alterações de código em conjunto com o autor das alterações. O revisor passará pelas alterações para garantir que as alterações sejam compreensíveis e suficientemente cobertas pelos testes. Portanto, o processo de revisão é manual, mas quando os testes (testes de unidade e integração e possivelmente testes de aceitação do usuário) passam nesse processo de revisão manual, tornam-se parte do processo de criação automática. Eles são executados toda vez que uma alteração é registrada.integração contínua O servidor executa essa tarefa como parte do processo de construção.
Os testes executados automaticamente mantêm a integridade do comportamento do código e ajudam a impedir que futuras alterações na base de código quebrem o código .
Por fim, o fornecimento de testes permite re-fatorar agressivamente o código, pois você pode tornar grandes melhorias de código seguras, sabendo que suas alterações não quebram os testes existentes.
Há uma ressalva para o Test Driven Development e é que você precisa escrever um código para torná-lo testável. Isso envolve codificar para interfaces e usar técnicas como injeção de dependência para instanciar objetos de colaboração. Confira o trabalho de Kent Beck, que descreve muito bem o TDD. Procure codificação para interfaces e estudePadrões de design