TDD vs. BDD
如果你一直在关注最新的软件开发,你一定听过测试驱动开发(Test-driven development TDD)和行为驱动开发(Behavior-driven development BDD)。这篇文章说明比较了这两种不同的开发模式,并提供了例子。
Test Drive Development,测试驱动开发
当我第一次听说TDD,就觉得它是一个很简单的概念,TDD是使用测试案例等来驱动你的软件开发。
如果我们想要更深入点了解TDD,我们可以将它分成五个不同的阶段:
1.首先,开发人员编写一些测试方法。
2.其次,开发人员使用这些测试,但是很明显的,测试都没有通过,原因是还没有编写这些功能的代码来实际执行。
3.接下来,开发人员实现测试中的代码。
4.如果开发人员写代码很优秀,那么在下一阶段会看到他的测试通过。
5.然后开发人员可以重构自己的代码,添加注释,使其变得整洁,开发人员知道,如果新添加的代码破坏了什么,那么测试会提醒他失败。
这种周期不断的循环下去,只要开发者有更多的功能需要开发。流程图如下:
Test-driven development flowchart
例子:
我们来看看一个开发人员是怎么来做着几个步骤的。这篇文章的完整的代码在:https://github.com/jdavis/tdd-vs-bdd,代码免费下载,你可以使用以下命令来运行:npm install && grunt。
比方说,开发人员希望写一个简单的函数来极端阶乘(这个例子很简单,但它会告诉我们TDD和BDD之间的差异)。TDD的常规做法是使用这个方法(function),然后断言(assert)计算结果符合条件。
在这个例子中,我们将使用Javascript的测试框架中的Mocha。测试应该和下面这个差不多:
var assert = require('assert'), factorial = require('../index');
suit('Test', function(){ setup(function(){ //Create any objects that we might need }); suit('#factorial()', function(){ test('equals 1 for sets of zero length', function(){ assert.equal(1, factorial(0)); }); test('equals 1 for sets of lengrh one', function(){ assert.equal(1, factorial(1)); }); test('equals 2 for sets of lengrh two', function(){ assert.equal(2, factorial(2)); }); test('equals 6 for sets of length three', function(){ assert.equal(6, factorial(3)); }); }); }); |
很明显,测试会失败,因为我们还没有写函数。然后让我们来写满足测试条件的函数。这些函数可能像下面这样:
module.exports = function(n) { if(n<0) return NaN; if(n===0) return 1;
return n*(factorial(n-1)); } |
现在我们运行这个测试,就可以通过了。下面我们看看BDD是怎样工作的。
Behavior-Driven Development ,行为驱动开发
好啦,现在你可能要问什么是BDD呢?这个定义呢,就有一点模糊了。有些人会说,它和TDD很像;还有人会说,这就是有着更好的指导的TDD。
不管它实际的定义是什么,这没有那么重要。最主要的是你要知道BDD可以消除TDD可能存在的问题。
和TDD比起来,BDD是需要我们先写行为规范(功能明细),在进行软件开发。功能明细和测试看起来非常相似,但是功能明细更加含蓄一些。
例子:
让我们继续看一下上面那个例子用BDD如何实现:
var assert=require('assert'), factorial = require('../index');
describe('Test', function(){ before(function(){ //Stuff to do before the tests, like imports, what not });
describe('#factorial()', function(){ it('should return 1 when given 0', function(){ factorial(0).should.equal(1); }); it('should return 1 when given 1', function(){ factorial(1).should.equal(1); }); it('should return 2 when given 2', function(){ factorial(2).should.equal(2); }); it('should return 6 when given 3', funcrion(){ factorial(3).should.equal(6); }); });
after(function(){ //Anything after the tests have finished }); }); |
最主要的区别在于描述的不同。BDD采用了更详细的方式使得它看起来就像是一句话。
这就是我所说的BDD可以解决一些TDD可能导致的问题。让你的测试看起来更像一个句子,是一种认知上的转变,你会更多的去考虑如何写你的测试。有一种说法是,如果你可以毫无障碍的阅读你的测试,你自然会写出更好的、更全面的测试。
这个例子很简单,我们不需要对其做过多的说明。BDD测试应该注重功能而不是实际的结果。你常常会听说BDD是帮助设计软件,而不是像TDD那样的测试软件。
TDD VS BDD
在TDD和BDD之间做选择是比较复杂的事情。这取决于你使用的语言是否有一个合适的测试框架,你的同事们是否熟悉他等等因素。
有些人认为BDD总比TDD要好。因为它能够消除TDD带来的问题。
BDD的关键在于,他并不是总能够保证阻止问题的发生。就像那些糟糕的代码组织或者是糟糕的设计的问题依然存在。使用测试让你写糟糕代码的可能性降低,从而有更强大的功能。
结论
哪一种测试方案会更好,这完全取决于个人。一个知道如何写优秀的TDD测试的人可能和另一个写优秀的BDD测试的人所写出代码的bug一样少。如果你发现你自己使用TDD写了不完整的测试,并希望设计更好的软件,那么不妨使用下BDD。如果你是一个学习TDD和BDD的新手,我建议你先学习TDD。这两种风格最重要的部分就是强制你写你代码的测试样例。如果你从不测试你的代码,你会需要他们的。
我不是一个研究TDD和BDD的专家。我只是知道他们之间的一点区别,并研究了以下。再次说明,文中的代码位于:https://github.com/jdavis/tdd-vs-bdd。
如果您对这篇文章有建议或错误改正。或者只是提出你的不同意的观点,我很乐意听到这一切。请随时与我联系。感谢您的阅读!
原文链接:
https://joshldavis.com/2013/05/27/difference-between-tdd-and-bdd/