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.
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
Teste errado
Instalando um novo tipo de output, consegui melhorar um pouco a saida de erro
Com a nova saida, e tudo ok.
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ê
Código
Teste errado
Teste ok
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!