quinta-feira, 21 de agosto de 2008

TDD na Prática - Parte II: Verificação e Confiabilidade

Como visto na Parte I, para criar código (que seja facilmente) "testável" é preferível escrever código que o testa primeiro.

Exercitar o código verificando seus limites e estados auxilia na descoberta de como o mesmo deve se comportar e traz um maior controle sobre seu funcionamento. Conseqüentemente, culmina em um maior nível de confiabilidade.

Tornar freqüente a verificação do código, de forma com que a cada alteração do mesmo ele seja novamente verificado, garante a manutenção deste nível de confiabilidade.

Verificar o código continuamente e acrescentar novas verificações à medida em que forem necessárias, além de re-executar todos os testes (teste de regressão), pode ser um processo doloroso se não for automatizado. Assim, existem diversas ferramentas que suavizam o processo, permitindo nos concentrar no que é importante.

Como o uso das ferramentas, em poucos (mili)segundos executamos todas as verificações e temos um maior grau de certeza que:

1) O novo código criado passa nos testes;

2) Após uma alteração no código, ele continua passando nos testes;

3) A alteração numa parte do código não fez outra parte do código parar de funcionar (compilar), nem deixar de funcionar como esperado (mudou o comportamento), pois ela também continua passando nos testes;

Para garantir 1) e 2) temos o Teste Unitário e para 3) o Teste de Integração e o Teste de Regressão.

Diversos frameworks de testes foram criados com esta finalidade, para cada linguagem. Em especial, os baseados na SUnit (como JUnit, CppUnit, DUnit, NUnit, etc.) são os preferidos por serem simples, poderosos e fáceis de adaptar a qualquer ambiente de desenvolvimento ou sistema operacional.

TDD, xUnit e xMock

A maioria dos desenvolvedores que adotam TDD, adotam também uma framework xUnit para execução dos testes. Não é diferente comigo, nem com este blog. Para cada linguagem há uma variedade de opções, com diversas vantagens e desvantagens a se ponderar. Por exemplo, para C++ existe também a Boost.Test, a CppUnitLite, a NanoCppUnit, a Unit++, a CxxTest e por aí vai. Tenho preferência pelas versões com maior adoção (como a CppUnit), apesar de que para determinadas aplicações, certos frameworks trazem vantagens interessantes.

Outra ferramenta importante, recomendada para usuários que já possuam alguma experiência em testes, é a de simulação de comportamento, para os chamados Objetos Substitutos, ou Mock Objects. Frameworks como jMock, MockPP, NMock, etc. etc. etc. trazem maneiras muito úteis de fazer construções que testem o comportamento esperado de objetos.

Enquanto os frameworks xUnit tem foco na verificação de estados de um objeto, os xMock tem foco na verificação do comportamento dos objetos, na interação entre os mesmos. É sempre possível simular os testes sem o auxílio de um framework, mas seu uso traz uma certa padronização na maneira com a qual os testes são construídos.

Com todas as facilidades e opções disponíveis, a adoção de um framework de testes passa a ser de extrema importância na implementação de TDD. Neste blog, você verá alguns deles em ação e saberá como a maioria deles funciona.

Nenhum comentário: