搬运-测试
Node.js下常用的测试框架mocha、should和一些基本测试方法
概念
1.单元测试
2.集成测试
3.系统测试
4.性能测试
5.benchmarking
6.行为驱动开发(BDD)
框架流程
1.测试框架Mocha
2.断言库should.js
3.Web测试库supertest
4.基准库benchmark
实践
npm install mocha -g
npm install should --save-dev
npm install supertest --save-dev
npm install benchmark --save-dev
mkdir test
code test/test.js
简单例子
使用官方提供的例子,验证数组的indexOf方法越界后是否返回-1,使用了Node.js自带的断言模块assert:
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(4));
})
})
})
- describe(),传进去的字符串可用来描述要测试的主体是什么,可以嵌套,这里要测试的主体就是 Array,indexOf 方法是其中的一个子描述
- it(),描述具体的case内容,里面包含断言的使用
执行后的输出:
$ mocha test.js
Array
#indexOf()
✓ should return -1 when the value is not present
1 passing (3ms)
修改 assert.equal(-1, [1,2,3].indexOf(4)); 中的值为 0,再执行,得错误断言:
$ mocha test.js
Array
#indexOf()
1) should return -1 when the value is not present
0 passing (6ms)
1 failing
1) Array
#indexOf()
should return -1 when the value is not present:
AssertionError [ERR_ASSERTION]: 0 == -1
+ expected - actual
-0
+-1
at Context.<anonymous> (test.js:5:14)
at processImmediate (internal/timers.js:461:21)
异步回调测试
写异步测试案例时只需在 it() 中添加一个回调函数(通常是done)
在上面的简单例子基础上,加入延时执行:
var assert = require('assert');
var async = function (callback) {
setTimeout(function(){
callback(assert.equal(-1, [1,2,3].indexOf(4)));
})
};
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(done) {
async(function (result) {
done(result);
})
})
})
})
Promise测试
mocha支持直接返回Promise,执行resolve测试成功,执行reject测试失败
var assert = require('assert');
var promise = new Promise(function(resolve, reject){
const result = [1,2,3].indexOf(4)
if(result == -1){
resolve(true)
}
else {
reject(false)
}
})
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
return promise
})
})
})
should.js使用
上面的例子如果用于判断复杂情况,可能需要写很多代码。使用should库可以为对象加上更多方法,而不用自己来实现和判断true和false了。
比如可以判断一个对象是否有这个属性,判断类型是否为字符串或数组。
var assert = require('assert');
var should = require('should');
describe('Should', function(){
it('should have property a ', function(){
({ a: 10 }).should.have.ownProperty('a');
})
})
should支持Promise,可以判断Promise的结果:
var should = require('should');
describe('Should', function(){
it('should return 10 ', function(){
return new Promise((resolve, reject) => resolve(10)).should.be.finally.equal(10);
})
});
Web接口测试
supertest可以直接调用superagent的接口,除此之外还新增了expect接口,可以验证status、header和body,以及在end函数里直接处理返回的数据。
var request = require('supertest');
var should = require('should');
describe('Accout', function(){
it('Opening account with password: password. Expecting success', function(done){
request('http://127.0.0.1:7000').post('/accounts/open')
.set('Accept', 'application/json')
.send({
secret: 'password'
})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err,res){
if (err) done(err);
res.body.should.have.property('success', true);
res.body.should.have.property('account').which.is.Object();
res.body.account.address.should.equal('1231414221412414');
res.body.account.publicKey.should.equal('faffasfa1f1414faaffafsfaf');
done();
})
})
})
可通过supertest设置请求路径和参数,对返回的response的status进行判断,并且直接通过end函数处理返回的内容,通过刚才的should库对body的属性进行检验,最后调用done结束。
性能测试
可以使用Node.js自带的console.time输出耗费时间,但如果有比较性的测试,比如需要知道哪个方案运行得更快,就需要benchmark库了:
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
// add tests
suite.add('RegExp#test', function(){
/o/.test('Hello World!');
})
.add('String#indexOf', function(){
'Hello World!'.indexOf('o') > -1;
})
// add listeners
.on('cycle', function(event){
console.log(String(event.target));
})
.on('complete', function(){
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
// run async
.run({ 'async': true });
结果:
$ node test.js
RegExp#test x 41,639,102 ops/sec ±1.62% (89 runs sampled)
String#indexOf x 731,668,178 ops/sec ±1.09% (87 runs sampled)
Fastest is String#indexOf
该例分别使用正则和查找索引来判断一个字符串是否含有“o”,其中,ops/sec测试结果显示的是每秒钟执行测试代码的次数(ops/sec),数值越大越好,同时还会显示测试过程中的统计误差。