September 21, 2011

BDD vs TDD

No ultimo #DevDojo, apareceu uma discussão interessante entre as diferenças entre o BDD e o TDD.

A melhor técnica para entender melhor algo é realizando ela na pratica. Decidi aplicar as duas técnicas para resolver o mesmo problema.

O problema

O problema é bem simples.

Quero um objeto Calculadora que some, subtraia, multiplique e divida dois números. A única peculiaridade é que a divisão deve retornar números decimais e que lance uma exception na divisão por 0 e não Infinito, como ocorre com divisão de decimais.

O resultado pode ser visto aqui <https://github.com/bltavares/BDD-vs-TDD>.

As semelhanças

Ambas as técnicas geram confiança no desenvolvimento. O código se torna algo saudável de manter e de desenvolver novas funcionalidades.

Uma coisa interessante é a implementação feita pelo minitest do bdd.

Uma expectativa é um assert renomeado.

image

Então, eles são iguais?

As diferenças

Se vocês seguirem os commits de cada branch, com os testes e os códigos lado a lado, verá que a maior diferença entre as duas técnicas está na organização e expressividade.

Desenvolvendo em bdd, senti que entendia melhor o motivo de um método existir e o que ele deveria fazer. A forma que você se aproxima do problema e suas soluções parecem ficar mais claras.

O código se torna mais organizado, mostrando o comportamento dos objetos e não apenas um teste dele sobre uma condição específica.

O tdd é mais rápido, mas me senti em dúvida sobre como deveria nomear metodos de acordo com o nome do teste. Ele não tornou claro para mim qual a especificação do objeto eu estava demonstrando.

As ferramentas

Utilizei o testunit para o TDD e o RSpec para o bdd. Vou apontar algumas características que afetam os frames e não as técnicas.

O testunit possui implementado tanto um framework de bdd quanto de tdd, permitindo que o dev escolha qual ele irá usar.

Uma coisa MUITO bacana dele é que os testes rodam de forma aleatória cada vez que você testa. Isso garante que nenhum dos casos esteja afetando outro caso.

Ele é bastante rápido, mas a saida de erro dele não foi muito interessante.

Código

image

Teste errado

image

Instalando um novo tipo de output, consegui melhorar um pouco a saida de erro

image

Com a nova saida, e tudo ok.

image

Com o rspec, acho bem mais espressivo a saida em formato de documentação, além de que, com um describe apenas é possivel setar o metodo subject como a instancia da classe sobre teste.

Ao descrever uma classe, o metodo subject instancia ela por padrão para você

image

Código

image

Teste errado

image

Teste ok

image

Conclusão

Apesar que os testes em tdd sejam bem mais rápidos, acho que vale a pena utilizar o bdd.

A melhor expressividade que essa aproximação para testes oferece ajuda a pensasr no problema real e não apenas no código, facilitando a comunicação de requerimentos entre programadores-stackholders, e inclusive programadores-programadores.

As duas formas são muito boas e bastante parecidas, cabendo ao dev escolher qual encaixa melhor ao seu estilo.

Mas o mais importante que trago desta experiência é: TEST IT!