O BDD adiciona mais um nível de abstração aos testes. O código de nível mais alto (geralmente em txt) descreve o que o sistema testa, o código de nível inferior descreve como o testa. Portanto, uma estrutura do BDD pode usar um framework TDD no código de nível inferior.
Isso ajuda muito ficando DRY. Por TDD você pode facilmente acabar com testes "molhados" contendo muita duplicação de código, o que os torna fáceis de quebrar refatorando o código e os testes com ele. Pelo BDD você tem que modificar apenas o nível de abstração mais baixo refatorando o código, então se a especificação não mudar, o código de nível mais alto não mudará.
Entre. isto é simples Clean Code, normalmente é suficiente ler o material de alto nível de abstração para entender o que ele faz, e se aprofundar no código de teste de nível de abstração mais baixo somente se você realmente precisar dele. Isso torna o código (de teste) mais fácil de entender em geral.
Um mau exemplo (porque é muito simples):
estilo TDD jasmim
calculator.add.specs
describe("Calculator: add", function (){
it("should be able to add 2 numbers together", function (){
var total = add(1, 2);
expect(total).toBe(3);
});
it("should be able to add 3 numbers together", function (){
var total = add(1, 2, 3);
expect(total).toBe(6);
});
});
estilo BDD jasmim-pepino
calculator.specs
feature('Calculator: add')
.scenario('should be able to add 2 numbers together')
.when('I enter "1"')
.and('I add "2"')
.then('I should get "3"')
.scenario('should be able to add 3 numbers together')
.when('I enter "1"')
.and('I add "2"')
.and('I add "3"')
.then('I should get "6"')
calculator.steps
featureSteps('Calculator:')
.before(function(){
this.values = [];
this.total = null;
})
.when('I enter "(.*)"', function(value){
this.values.push(Number(value));
})
.when('I add "(.*)"', function(value){
this.values.push(Number(value));
})
.then('I should get "(.*)"', function(expectedTotal){
this.total = add.apply(null, this.values);
expect(this.total).toBe(Number(expectedTotal));
});
implementação
calculator.js
function add(){
var args = Array.prototype.slice.call(arguments);
var total = 0;
for (var i in args)
total += args[i];
return total;
}
Agora, se eu renomear a função add()
para sum()
, terei que alterar o código TDD em 2 locais, enquanto o código BDD estará em um único local no arquivo etapas . Ofc. adicionar mais um nível de abstração requer mais código ...