Muito tem se falado e se escrito sobre a realização de testes no processo de desenvolvimento de software. Bastante coisa interessante vem acontecendo neste cenário e isso é muito interessante, pois testes são de extrema importância para a qualidade de software.

Automatizar testes (sejam eles unitários, de integração ou aceitação) é uma tarefa que tem se tornado cada vez mais simples devido aos frameworks de testes e ferramentas que oferecem suporte para os mesmos. As IDEs estão cada vez mais completas e possuem suporte para integração com os frameworks, o que facilita e agiliza o ato de testar software. Também temos as ferramentas de integração contínua, que podem ser configuradas para trabalhar em conjunto com os frameworks de teste, o que torna a automação bastante completa.

Uma sigla já bem conhecida e divulgada no cenário de desenvolvimento de software é TDD. Test Driven Development (TDD) significa guiar o desenvolvimento de software através de testes. Na prática, primeiro é escrito o teste para que posteriormente seja escrito o código que vai atender a determinada funcionalidade. O teste valida se o código está em conformidade com a funcionalidade que se propõe implementar, caso esteja, diz-se que o código passou no teste, caso contrário, não. Ou seja, após definir qual funcionalidade será implementada, escreve-se um teste onde o código que passe neste teste estará, consequentemente, implementando a funcionalidade. Diversos autores já escreveram sobre TDD, dando sua importante colaboração para o cenário de desenvolvimento de software.

Porém, em minha opinião, vejo na TDD uma “técnica” muito mais importante para o design de software do que propriamente para testes. Tendo como objetivo escrever código que passe em um teste, muitas vezes o desenvolvedor “se vê obrigado” a utilizar técnicas de programação que diminuem o acoplamento entre classes e que cada classe e seus métodos tenham seus papéis muito bem definidos, fazendo com que cada teste específico possa ser realizado sem a preocupação de testar outras tantas funcionalidades. Com isso técnicas como refactoring e dependency injection acabam sendo amplamente aplicadas, o que torna o design limpo e coeso.

Mas com todo esse movimento em torno de testes de software e TDD, algumas coisas tem se confundido. Testar software é executar os diversos testes em cima de código escrito. Ou seja, depois de escrito uma determinada funcionalidade, executa-se os testes e checa-se o resultado. Caso o código escrito tenha passado nos testes diz-se que está em conformidade com a funcionalidade que se propõe a implementar, livre de bugs, e apto à produção. TDD é desenvolvimento guiado por testes, ou seja, a partir de testes se escreve código.

Quando utilizamos TDD consequentemente testamos software, e isso é bom! Aplicando TDD garantimos um design limpo, coeso, e ao executar os testes efetivamente testamos o software, logo temos as duas abordagens sendo utilizadas. Mas não necessariamente quem testa software faz TDD. Nem mesmo quem automatiza teste necessariamente faz TDD. Um exemplo que tenho visto bastante é de equipes que escrevem código e depois os testes para atestar a qualidade do código anteriormente escrito. Isso não é TDD. Pode até parecer que não existe diferença entre escrever o código e depois o teste ou o teste depois o código, já que o importante é o teste existir, mas é como eu disse anteriormente, TDD não está relacionado a teste está relacionado a design. E, em minha opinião, está muito mais relacionado a design do que a teste. Quando se escreve um teste antes do código, a intenção no momento em que vai se escrever o código é de passar no teste, e a intenção do teste é aplicar regras para que a funcionalidade seja implementada e que esteja correta.

Hoje pela manhã li um bom post escrito por Uncle Bob, onde ele comenta sobre testes gerados automaticamente e TDD. Testes que são gerados automaticamente, são gerados a partir de código escrito! E se o código foi escrito antes do teste, não foi feito TDD. Isso não invalida o que foi feito, afinal, foi aplicado um teste, porém não foi feito TDD.

Concluindo, TDD para mim está muito mais relacionado a design do que a testes, já que o design é feito de maneira diferente quando se aplica TDD do que quando simplesmente se realiza testes depois do código escrito.

Abaixo um pequeno trecho do post que mencionei do Uncle Bob.

In TDD, programmers state their intent twice; once in the test code, and again in the production code. These two statements of intent verify each other. The tests, test the intent of the code, and the code tests the intent of the tests. This works because it is a human that makes both entries! The human must state the intent twice, but in two complementary forms. This vastly reduces many kinds of errors; as well as providing significant insight into improved design.

Using a test generator breaks this concept because the generator writes the test using the production code as input. The generated test is not a human restatement, it is an automatic translation. The human states intent only once, and therefore does not gain insights from restatement, nor does the generated test check that the intent of the code was achieved. It is true that the human must verify the observations, but compared to TDD that is a far more passive action, providing far less insight into defects, design and intent.

É basicamente isso, espero que tenham gostado do meu primeiro post ;)

2 Comentários

  1. Sim, TDD é uma técnica de design que por consequência traz uma suíte de testes automatizados. Dê uma olhada em Behavior-Driven Development, também, que é uma ‘evolução filosófica’ neste sentido.

    []s

  2. MOço, bom demais!
    pode me adicionar no msn e gmail para batermos um papo?
    vpmota@gmail.com
    v_mota@hotmail.com


Comente

*
*