Unit testing(单元测试)
单元测试往往只关注于一个代码片段,通常是一个模块或函数,测试代码应该比较简单,可以快速实现和运行。这也意味着你会写很多的单元测试用例来保证代码的功能正常。单元测试应该没有什么依赖,比如通过网络请求获取数据库数据。单元测试的基本原则就是:多个测试用例,每个测试不同的功能并且相互之间没有依赖。单元测试在库和框架的开发中比较常见。
TDD(测试驱动开发)
TDD(Test Drive Development),用测试来驱动软件的开发,它有以下几个步骤:
- 开发者首先写一些测试
- 开发者运行这些测试,但这些测试明显都会失败,因为你并没有实现代码细节
- 开发者实现代码细节
- 如果开发者顺利实现代码的话,运行所有测试就会通过
- 开发者可以重构代码,如果新代码功能不正确的话,对应的测试文件也会失败
从以上描述可以看出,TDD要求在写代码前考虑好所有的边界情况,然后你写出的代码能够保证通过这些测试。如果测试写的足够全面,当重构时会节省大量时间。
下面是一个使用TDD的示例,计算阶乘的函数,测试框架使用的Mocha
测试代码
var assert = require('assert'),
factorial = require('../index');
suite('Test', function (){
suite('#factorial()', function (){
test('equals 1 for sets of zero length', function (){
assert.equal(1, factorial(0));
});
test('equals 1 for sets of length one', function (){
assert.equal(1, factorial(1));
});
test('equals 2 for sets of length 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);
}
并不是所有的项目都适合用TDD测试,如果项目中模块间的依赖度很高,又或者功能经常变动,那么这种测试方式就是得不偿失的
BDD 行为驱动测试
BDD(Behavior Drive Development),应该是写业务代码中使用较多的一种测试方式,它强调的是根据用户的行为得到正确的反馈,BDD需要产品确定好需求文档,然后开发人员根据文档描述完成功能实现,这是一种比较贴近自然语言的测试方式,但是这种方式可能不如TDD测试的全面
下面是使用BDD测试写的计算阶乘的函数
module.exports = function (n) {
if (n < 0) return NaN; // 如果需求没要求对负数进行处理,可能会忽略这行代码
if (n === 0) return 1;
return n * factorial(n - 1);
}
var assert = require('assert'),
factorial = require('../index');
describe('Test', function (){
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', function (){
factorial(3).should.equal(6);
});
});
});
总结一下就是,使用TDD方式时,你要站在测试工程师的角度去思考功能的实现。而BDD的方式,你要站在产品经理的角度去思考功能的实现。具体使用哪种方式要根据项目实际情况分析,BDD是一种开发人员接受度较高的测试方式。