初识 mocha in Nodejs
初识 mocha in Nodejs
囧,cnodejs不能上传图。有图版请见 无图无真相!
NodeJS里最常用的测试框架估计就是mocha了。它支持多种node的assert libs, 同时支持异步和同步的测试,同时支持多种方式导出结果,也支持直接在browser上跑Javascript代码测试。
本文示例大多源于官网示例,部分示例结合需要或自己的感想有所改动。更多介绍请看 官方网址:Mocha on Github
Installation:
当你成功安装nodejs v0.10 和 npm后执行下面这条命令。
# npm install -g mocha
p.s. Ubuntu的注意apt源里的nodejs版本会比较旧,某些module会不支持,请从nodejs官网进行源码安装。
First step to Mocha:
以下为最简单的一个mocha示例:
var assert = require("assert");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
})
})
});
- describe (moduleName, testDetails) 由上述代码可看出,describe是可以嵌套的,比如上述代码嵌套的两个describe就可以理解成测试人员希望测试Array模块下的#indexOf() 子模块。module_name 是可以随便取的,关键是要让人读明白就好。
- it (info, function) 具体的测试语句会放在it的回调函数里,一般来说info字符串会写期望的正确输出的简要一句话文字说明。当该it block内的test failed的时候控制台就会把详细信息打印出来。一般是从最外层的describe的module_name开始输出(可以理解成沿着路径或者递归链或者回调链),最后输出info,表示该期望的info内容没有被满足。一个it对应一个实际的test case
- assert.equal (exp1, exp2) 断言判断exp1结果是否等于exp2, 这里采取的等于判断是== 而并非 === 。即 assert.equal(1, ‘1’) 认为是True。这只是nodejs里的assert.js的一种断言形式,下文会提到同样比较常用的should.js。
如果exp1和exp2均为字符串,字符串比较出错时则控制台会用颜色把相异的部分标出来。
Asynchronous
Frist step 中的代码显然是个 Synchronous 的代码,那么对于异步代码应该怎么做呢?很简单,在你最深处的回调函数中加done()表示结束。
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
})
})
})
- done ()<br> 按照瀑布流编程习惯,取名done是表示你回调的最深处,也就是结束写嵌套回调函数。但对于回调链来说done实际上意味着告诉mocha从此处开始测试,一层层回调回去。
上例代码是test pass的,我们尝试把test.ls改成不存在的test.as。便会返回具体的错误位置。
这里可能会有个疑问,假如我有两个异步函数(两条分叉的回调链),那我应该在哪里加done()呢?实际上这个时候就不应该在一个it里面存在两个要测试的函数,事实上一个it里面只能调用一次done,当你调用多次done的话mocha会抛出错误。所以应该类似这样:
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
})
it('should read test.js without error', function(done){
fs.readFile('test.js', function(err){
if (err) throw err;
done();
});
})
})
})
Pending
即省去测试细节只保留函数体。一般适用情况比如负责测试框架的写好框架让组员去实现细节,或者测试细节尚未完全正确实现先注释以免影响全局测试情况。这种时候mocha会默认该测试pass。 作用有点像Python的pass。
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
})
})
});
Exclusive && Inclusive
其实很好理解,分别对应only和skip函数。
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it.skip('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
})
it('should read test.js without error', function(done){
})
})
})
上面的代码只会有一个test complete, 只有only的会被执行,另一个会被忽略掉。每个函数里只能有一个only。如果是it.skip ,那么该case就会被忽略。
only和skip共用没有什么实际意义,因为only的作用会把skip屏蔽掉。
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it.skip('should read test.ls without error', function(done){
fs.readFile('test.as', function(err){
if (err) throw err;
done();
});
})
it('should read test.js without error', function(done){
})
})
})
上面的代码尽管test.as不存在,但是由于skip,依然会显示test complete。
Before && After
单元测试里经常会用到before和after。mocha同时还提供了beforeEach()和afterEach()。 这里为方便阅读用livescript表示,!->可理解成function(){}。细节无需细读,只需通过框架了解这几个函数如何使用便可。
require! assert
require! fs
can = it
describe ‘Array’, !->
beforeEach !->
console.log ‘beforeEach Array’
before !->
console.log 'before Array'
before !->
console.log 'before Array second time'
after !->
console.log 'after Array'
describe '#indexOf()', !->
can 'should return -1 when the value is not present', !->
assert.equal -1, [1,2,3].indexOf 0
can 'should return 1 when the value is not present', !->
describe 'File', !->
beforeEach !->
console.log 'beforeEach file test!'
afterEach !->
console.log 'afterEach File test!'
describe '#readFile()', !->
can 'should read test.ls without error', !(done)->
fs.readFile 'test.ls', !(err)->
if err
throw err
done!
can 'should read test.js without error', !(done)->
fs.readFile 'test.js', !(err)->
if err
throw err
done!
由结果可知(after的使用与before同理),
- beforeEach会对当前describe下的所有子case生效。
- before和after的代码没有特殊顺序要求。
- 同一个describe下可以有多个before,执行顺序与代码顺序相同。
- 同一个describe下的执行顺序为before, beforeEach, afterEach, after
- 当一个it有多个before的时候,执行顺序从最外围的describe的before开始,其余同理。
Test Driven Develop (TDD)
mocha默认的模式是Behavior Driven Develop (BDD),要想执行TDD的test的时候需要加上参数,如
mocha -u tdd test.js
前文所讲的describe, it, before, after等都属于BDD的范畴,对于TDD,我们用suite, test, setup, teardown。样例代码如下:
suite 'Array', !->
setup !->
console.log 'setup'
teardown !->
console.log 'teardown'
suite '#indexOf()', !->
test 'should return -1 when not present', !->
assert.equal -1, [1,2,3].indexOf 4
<hr>
TDD的一些相关资料:
- What is TDD :
- Difference between TDD && BDD :
http://stackoverflow.com/questions/4395469/tdd-and-bdd-differences
初识 Mocha in Node.js
在Node.js中,Mocha是最常用的测试框架之一。它不仅支持多种Node.js的断言库,还支持异步和同步测试,并且可以以多种方式输出结果,甚至可以直接在浏览器中运行JavaScript代码进行测试。
安装
确保你已经安装了Node.js v0.10及以上版本和npm。然后执行以下命令来全局安装Mocha:
$ npm install -g mocha
如果你使用的是Ubuntu系统,需要注意系统的APT源中的Node.js版本可能较旧,某些模块可能不支持。建议从Node.js官网下载并安装最新版本。
第一步:Mocha 示例
以下是一个简单的Mocha示例:
var assert = require("assert");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
关键概念
-
describe(moduleName, testDetails):
describe
用于描述模块和子模块。例如,上述代码中的describe
表示要测试Array
模块下的#indexOf()
子模块。 -
it(info, function): 具体的测试语句会放在
it
的回调函数里。info
字符串通常用来描述期望的正确输出。如果某个it
块中的测试失败,控制台会打印详细信息。 -
assert.equal(exp1, exp2): 使用
assert.equal
来断言exp1
是否等于exp2
。这里的判断是基于==
而不是===
。
异步测试
如果需要测试异步代码,可以在最深层的回调函数中调用 done()
函数来表示测试完成:
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
});
});
});
关键概念
- done():
在异步测试中,调用
done()
表示测试完成。如果在it
块中有多个异步操作,每个操作都需要调用done()
。
待办测试
如果暂时不想实现测试细节,可以使用空的 it
块:
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
// 留待实现
});
});
});
排除和包含测试
使用 it.skip
可以排除某个测试,而 it.only
可以指定只运行某个测试:
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it.skip('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
});
it('should read test.js without error', function(done){
fs.readFile('test.js', function(err){
if (err) throw err;
done();
});
});
});
});
前置和后置操作
使用 before
, after
, beforeEach
, afterEach
可以设置一些前置和后置的操作:
require('assert');
require('fs');
const can = it;
describe('Array', function(){
beforeEach(function(){
console.log('beforeEach Array');
});
before(function(){
console.log('before Array');
});
after(function(){
console.log('after Array');
});
describe('#indexOf()', function(){
can('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
测试驱动开发 (TDD)
Mocha 默认采用行为驱动开发 (BDD) 模式,但也可以切换到测试驱动开发 (TDD) 模式:
$ mocha -u tdd test.js
TDD 模式的代码示例:
suite('Array', function(){
setup(function(){
console.log('setup');
});
teardown(function(){
console.log('teardown');
});
suite('#indexOf()', function(){
test('should return -1 when not present', function(){
assert.equal(-1, [1,2,3].indexOf(4));
});
});
});
以上就是Mocha的基本使用方法,希望对你有所帮助!
好文,收藏~
学习下。支持
今天刚好准备学习nodejs测试,果断收藏
顶起, 还了解到livescript.
不错文章,社区支持图片就好了
让你爱上写测试的感觉哈哈
md不能直接上传图片,所以要等社区添加个上传图片的功能啦
md可以贴图… 大家都是搞技术的…找个传图片的地方不难吧… 真找不到就用这个 upload
原来还有这玩意。。是私有接口,还是大家都可以用的。可以宣传一下。。
very nice
收藏!
收藏!
写得很好。
不过Pending tests这个有点问题。不是像你所说的“省去测试细节只保留函数体”,而是不指定回调函数:
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present');
});
});
感谢指正。确实是的,应该是without callback。但CnodeJS好像日志时间久了就不给修改了?
求问,为什么我按上面的步骤安装完mocha后,复制第一个实例,运行后报错: describe is not defined??求问
我的node版本是v.10.5
你require了相应的模块吗?第一个demo可是官方demo啊~
问下楼主,it前后可以写before或者after吗?(也就是在describe里边)
好东西
收藏
收了
发现单元测试真的很重要,找时间把这块做起来
我觉得这个论坛程序必须要采取些防挖坟措施了,老是看到几年前的帖子被顶上来。。。
收起。
目前支持 ecs6的特性嘛 最近新安装了一个co-mocha说是支持的,但是在实际应用中,却不支持,会报类似这样的错误:
import Fetcher from ‘…/lib/mail_fetcher/126’; ^^^^^^ SyntaxError: Unexpected token import
以前一直都是一知半解,看完此文犹如醍醐灌顶!!!!
mark
mark
mark
我是windows系统 npm install -g mocha 成功了 node app.test 提示 describe is not defined mocha app.test 提示 ‘mocha’ 不是内部或外部命令,也不是可运行的程序或批处理文件。 我的node版本 是 v0.12.7 这个怎么破 求帮忙
mark
mark
mark
mark
棒棒的
初识 mocha in Nodejs
NodeJS里最常用的测试框架之一就是mocha了。它支持多种node的assert库,同时支持异步和同步的测试,并且支持多种方式导出结果,也支持直接在浏览器上运行JavaScript代码测试。
本文示例大多来源于官方示例,部分示例结合需求或个人感想有所改动。更多介绍请查看官方网址:Mocha on Github。
Installation
当你成功安装Node.js v0.10和npm后,执行下面这条命令来安装mocha:
# npm install -g mocha
注意: 在Ubuntu系统上,源中的Node.js版本可能较旧,某些模块可能不支持,请从Node.js官网下载并安装最新版本。
First Step to Mocha
以下为最简单的mocha示例:
var assert = require("assert");
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
describe (moduleName, testDetails)
describe
可以嵌套,比如上述代码中的 describe
嵌套可以理解为测试人员希望测试 Array
模块下的 #indexOf()
子模块。moduleName
可以随意取名,关键是要让读者能理解其含义。
it (info, function)
具体的测试语句会放在 it
的回调函数里,info
字符串通常用来描述期望的正确输出。当 it
block 内的测试失败时,控制台会打印详细的错误信息。一般是从最外层的 describe
开始输出,最后输出 info
,表示期望的 info
内容未被满足。
assert.equal (exp1, exp2)
断言判断 exp1
是否等于 exp2
。这是 assert.js
的一种断言形式,例如 assert.equal(1, '1')
认为是 True
。这与 ===
不同。
异步测试
上例中的代码是同步的,那么对于异步代码应该怎么做呢?只需要在最深处的回调函数中添加 done()
即可表示结束。
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
});
});
});
done ()
done()
表示你已完成了所有的工作,回调链已经结束。mocha
会在调用 done()
之后检查测试是否完成。
省略测试细节 (Pending)
省略测试细节仅保留函数体。这通常用于框架开发,让团队成员实现细节,或者测试细节尚未完全实现时防止影响全局测试情况。
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
});
});
});
Exclusive & Inclusive
only
和 skip
函数分别用于排除和包含测试。
fs = require('fs');
describe('File', function(){
describe('#readFile()', function(){
it.skip('should read test.ls without error', function(done){
fs.readFile('test.ls', function(err){
if (err) throw err;
done();
});
});
it('should read test.js without error', function(done){
fs.readFile('test.js', function(err){
if (err) throw err;
done();
});
});
});
});
上面的代码中只有 it
不带 skip
的测试会被执行。
Before & After
在单元测试中常用到 before
和 after
。mocha还提供了 beforeEach
和 afterEach
。
require('assert');
require('fs');
describe('Array', function(){
beforeEach(function(){
console.log('beforeEach Array');
});
before(function(){
console.log('before Array');
});
after(function(){
console.log('after Array');
});
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
beforeEach
对当前 describe
下的所有子测试有效。before
和 after
的代码没有特殊的顺序要求。