Prática 6. Desenvolvimento Guiado por Testes
OBS Atenção: Quem não está acostumado com o termo, pode confundir “Teste Automatizado” com “Teste Automático”, mas estes são duas coisas diferentes. Para ser “automático”, bastaria uma ferramenta que fizesse uma bagatela de testes partindo de um simples clique num botão. Já para um teste “automatizado”, alguém tem que “automatizá-lo”, ou seja, implementar uma rotina que efetue os testes desejados. É este segundo cenário que chamamos de “Testes Automatizados”.
Os Testes Automatizados avisam se o código continua produzindo as mesmas respostas após ter sido alterado, provendo uma enorme segurança ao processo de Refatoração e injetando coragem no desenvolvedor.
Como os testes precisam ser implementados pelo desenvolvedor, produzi-los é um investimento que gera retornos no futuro, tais como:
Por serem implementados, os testes se tornam grandes aliados para o entendimento do design do sistema, servindo de “documentação” para a compreensão do código fonte;
Sempre que um teste detecta uma falha, a equipe ganha tempo de desenvolvimento, pois tem a oportunidade de corrigir o problema rapidamente;
Evita longas sessões de depuração que costumam tomar boa parte do tempo dos projetos
“Quanto mais tempo se leva para descobrir que você cometeu um erro, mais caro é para corrigi-lo” (BOEHM, 1988)
O XP trabalha com dois tipos de testes:
Teste de Unidade: é realizado sobre cada unidade (classe, método ou função) do sistema com a finalidade de verificar se os resultados gerados estão corretos;
Teste de Aceitação: são efetuados sobre cada História do sistema, verificando não apenas uma unidade em particular, mas as interações entre um conjunto de classes ou rotinas que implementam uma funcionalidade.
Para implementar os testes, a equipe pode fazer uso de frameworks de testes, que já possuem diversas funcionalidades, permitindo asserções para várias situaçõe
Uma característica importante do TDD é o conceito de “test-first”, ou seja, “primeiro o teste”. Isso significa que cada nova funcionalidade, após ser devidamente pensada, deve ter seu Teste de Unidade implementado “antes que a funcionalidade em si seja implementada” (SOMMERVILLE, 2011).
Isso força o desenvolvedor a “pensar antes de fazer”, o que gera código mais simples de entender e livre de remendos, que poderiam ser causados por erros de design.