作为过来人,首先想说的是: 不要怕!
刚从前端转来做Node的,从来没接触过单元测试,一听这个名词就觉得高大上。加上周围一些前端儿也基本没有接触过单元测试,总把单元测试看得比较遥远,中文教程也点到即止并有点过分重视命令行参数的讲解,让我迟迟不敢轻易入坑。
然而,当项目确实希望用到单元测试的时候,我决定抛开内心的恐惧,硬着头皮认认真真地读英文版的Mocha和chai Assert文档,发现,真的不过如此而已!远远没有想象中的难,Hour级入门。
现在,我有一种感觉:不跑单元测试会让我感到恐慌。。。
这一次又给了我深刻的教训:接触一个新技术的时候,不要慌,不要害怕,不过分依赖过来人的看法,不亲自实践又怎知难易呢?
罗里吧嗦了一大堆,现在开始步入正题。。。
单元测试分为两种:
对于TDD、BDD的区别可查看: 关于TDD、BDD和DDD的一些看法 。
对于单元测试,推荐查看 【译】每个单元测试必须回答的 5 个问题 。
mocha默认的模式是BDD。
在Node.js中,目前比较流行的单元测试组合是 mocha + chai
。mocha是一个测试框架,chai是一个断言库,所以合称”抹茶”。
断言库类型有: jasmine
、 should.js
、 chai
、 assert
。哪个更好主要看团队和项目需要吧,个人喜欢chai断言库的assert风格,更接近原生也更人性化。
Mocha主要特性有:
本文使用的是: Mocha + chai(assert风格)
。
npm install mocha -g npm install mocha npm install chai
mocha [debug] [options] [files] 如: mocha --recursive test/
Mocha有三个基本方法:
describe是可嵌套的,描述测试用例是否正确。
describe('测试模块的描述', function() { // .... });
info为描述性说明。一个it对应一个单元测试用例。
describe('单元测试的描述,一般写明用途和返回值', function() { // .... });
mocha的断言语句,判断exp1是否等于exp2。
一个it里面只有一个done。
done标识回调的最深处,也是嵌套回调函数的末端。
备注:在mocha v3.x版本,Promise回调不需要使用 done
来标识回调最深处,并且在Promise回调中是用done回报错。
describe('User', function() { describe('#save()', function() { it('should save without error', function(done) { var user = new User('Luna'); user.save(done); }); }); });
before()
、 after()
、 beforeEach()
、 afterEach()
是基于BDD风格提出的。用于预处理和test后的处理。
Test Hooks方法的几个注意点:
describe('hooks', function() { before(function() { // runs before all tests in this block }); after(function() { // runs after all tests in this block }); beforeEach(function() { // runs before each test in this block }); afterEach(function() { // runs after each test in this block }); // test cases });
Hooks的三种写法:
beforeEach(function() { }); beforeEach(function nameFun() { }); beforeEach("some description", function() { });
describe块和it块都允许调用 only()
和 skip()
方法。
only()
方法表示在当前的父describe块下,只执行该单元的测试。
skip()
方法表示在当前的父describe块下,跳过不执行该单元的测试。
当在一个describe块下,同时存在 only()
和 skip()
方法,则只执行 .only()
方法。
describe('Array', function() { describe.only('父describe块下只执行该测试单元', () => { it.skip('跳过的测试单元', () => { //... }); }); describe('不执行', () => { //... }); });
Mocha默认运行/test子目录里面的测试脚本。
Mocha默认只执行/test子目录下第一层的测试用例。
所以,应加上–recursive参数,使全部子目录下的测试用例都能被执行。
mocha --recursive
mocha默认的模式是BDD,要想执行TDD的test时需要加上参数,如:
mocha -u tdd test.js
--watch
参数用来监视指定的测试脚本。当脚本发生变化,就会自动运行mocha。
mocha --watch
只要有一个测试用例没有通过,就会停止执行后面的测试用例。
Mocha默认每个测试用例最多执行2000毫秒。如果2000毫秒后还没有执行完成,则报错。-t可执行超时门槛。
mocha -t 5000 test.js
mocha spec/{my,awesome}.js mocha test/unit/*.js mocha 'test/**/*.@(js|jsx)'
我个人比较喜欢assert风格。具体可查看文档: http://chaijs.com/api/assert/
其实最常用的API也就那几个: