quinta-feira, 25 de fevereiro de 2010

Testar antes (TDD) ou depois?

Sei que esse assunto está mais do que batido, mas gostaria de colocar aqui minhas impressões sobre o tema.

Testes automatizados de software estão se tornando requisitos obrigatórios para qualquer projeto que tenha algum tipo de controle de qualidade. Assim como em qualquer ramo da industria, um controle de qualidade implica no aumento dos custos de produção. Para o consumidor isso é claro, e se resume naquela conhecida frase: "O Barato saí caro". O produto mais barato geralmente tem uma qualidade pior, o que significa um controle de qualidade inexistente ou tolerante à falhas.

Do lado de cá dessa controversa industria que é o desenvolvimento de software, há uma certa resistência quanto à necessidade de um controle de qualidade, principalmente aqui no Brasil.

Na minha visão sobre esse assunto, o problema está na forma como os projetos são gerenciados atualmente. Hoje, na maioria dos projetos, o custo de desenvolvimento de um software se resume à simples conta: ValorTotalDaHoraDoDesenvolvedor * QtdeHorasDoProjeto.

Levando em consideração que o desenvolvimento de uma rotina de testes (teste unitário), geralmente consome a mesma quantidade de tempo necessária para se escrever a própria rotina à qual o teste avalia, em alguns cenários, um projeto com 100% de cobertura de testes pode levar o dobro do tempo para ser desenvolvido. Isso se complica ainda mais se a equipe não está acostumada com a ideia de se escrever testes.

E é aí que o TDD faz o maior sentido do mundo. Assim como em qualquer indústria, bons gestores se esforçam para reduzir os custos nos processos de produção. Enquanto aqui no Brasil isso parece se refletir únicamente na redução direta do Valor/Hora citado acima, outras esferas procuram soluções mais efetivas e inteligentes.

No TDD (Test Driven Development), o teste unitário deve ser escrito antes da rotina que ele deve avaliar, e este geralmente reflete uma definição de como a rotina deve funcionar, servindo inclusive como uma especificação. Após escrito, o teste é então executado com a certeza de que irá falhar, já que a rotina não foi implementada ainda. Em seguida é escrita a rotina alvo do teste, que deve seguir a especificação definida no mesmo. Uma nova execução vai agora indicar se a rotina atende à especificação, e caso não atenda ela deve ser refatorada até que tenhamos um resultado positivo na execução do teste.

Mas qual é o motivo lógico de se criar um teste unitário antes da própria rotina? Ao longo do tempo, um desenvolvedor que adota TDD, se acostuma com esse "jeito de pensar", e passa a naturalmente pensar numa rotina de testes antes de pensar na própria rotina alvo. Isso, certamente agiliza o seu trabalho, já que passa a ser uma reação automática do desenvolvedor, assim como um motorista muda de marchas sem ter que raciocinar a respeito.

TDD é uma cultura, um mindset, uma sacada gerencial para reduzir o tempo gasto na escrita de testes unitários. Porém, TDD só dá resultados a longo prazo, depois de muita prática.

E note que TDD não é para todos, existem certamente casos em que ele não se aplica, como por exemplo quando temos um departamento ou pessoa responsável pelos testes do projeto. As responsabilidades neste cenário é dividida entre o desenvolvedor do teste e o desenvolvedor da rotina. E se o teste é escrito antes ou depois, não tem mais importância, já que não faz diferença em termos de redução de custos.