mocha + chai + supertest 测试 node server
要在Nodejs中写单元测试的话,你需要知道用什么测试框架,怎么测试异步函数,怎么测试私有方法,怎么模拟测试环境,怎么测试依赖HTTP协议的web应用,需要了解TDD和BDD,还有需要提供测试的覆盖率。
测试技术栈
- mocha
- chai
- supertest
Mocha 是一个功能丰富的Javascript测试框架,它能运行在Node.js和浏览器中,支持BDD、TDD、QUnit、Exports式的测试。Mocha本身不带断言库,所以必须先引入断言库, 官网
Chai 是一个BDD/TDD的断言库,官网。
所谓"断言",就是判断源码的实际执行结果与预期结果是否一致,如果不一致就抛出一个错误。
Chai提供expect
和should
两个BDD风格的API,二者使用相同的链式语言来组织断言,但不同在于他们初始化断言的方式:expect
使用构造函数来创建断言对象实例,而should
通过为Object.prototype
新增方法来实现断言(所以should不支持IE);expect
直接指向chai.expect
,而should
则是chai.should()
// 引入断言库
var chai = require('chai') ,
expect = chai.expect ,
should = chai.should();
// 相等或不相等
expect(4 + 5).to.be.equal(9);
expect(4 + 5).to.be.not.equal(10);
expect(foo).to.be.deep.equal({ bar: 'baz' });
// 布尔值为true
expect('everthing').to.be.ok;
expect(false).to.not.be.ok;
// typeof
expect('test').to.be.a('string');
expect({ foo: 'bar' }).to.be.an('object');
expect(foo).to.be.an.instanceof(Foo);
// include
expect([1,2,3]).to.include(2);
expect('foobar').to.contain('foo');
expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
// empty
expect([]).to.be.empty;
expect('').to.be.empty;
expect({}).to.be.empty;
// match
expect('foobar').to.match(/^foo/);
supertest 专门用于 http 请求的断言
针对函数的测试
待测函数add.js
function add (a, b) {
return a + b;
}
module.exports = add;
测试普通函数test.js
const expect = require('chai').expect; // 引入chai
const add = require('./add.js'); // 引入add.js
describe('test add function', function () {
it('1 + 2 = 3', function () {
expect(add(1 + 2)).to.be.equal(3);
})
})
之后运行,得到测试结果。
mocha test.js
针对异步函数测试
对于异步执行的函数,外部不能直接知道什么时候函数执行完了。因此,mocha框架会传入一个callback (done)
,当异步调用完成之后,执行这个callback
,告诉mocha
这个函数执行完了。看个例子。
decribe('asyn test', function () {
it('asyn test', function (done) {
...
done();
})
})
针对接口测试
测试get请求
const request = require('supertest');
const expect = require('chai').expect;
const app = require('../app.js'); // 这里是express框架自动生成的app.js
describe('test get request', function () {
it ('get a image', function (done) {
request(app)
.get('/')
.expect(200, done);
})
});
测试时不用启动服务器,supertest会自动去执行代码,可以在指定路由下面打log,看是否执行。写好测试代码之后,执行
mocha ./test/test.js
post请求
只写it
函数里面的内容。
request(app)
.post('/login')
.send(data) // send a json data
.expect(200)
.end(function (req, res) {
expect(res.status).to.be.equal('ok'); // 请求完成测试请求内容是否符合预期
done();
})
set cookie
要设置cookie需要用到supertest的agent模拟客户端
decribe('set cookie', function () {
it ('set cookie', functin (done) {
const agent = request.agent(app); // agent 代替request,其余不变
agent
.get('/')
.set('Cookie', ['token=fdjasklfdsla']) // set cookie
.expect(200, done)
})
})
change host
supertest 默认host是127.0.0.1,对于一些需要特定host访问的接口,可以这样修改host
agent.set('host', 'HOST')
设置超时时间
supertest 默认请求超时时间是2000ms,很多异步请求都没有完成就被判死刑了。所以需要手动设置超时时间。
// 在代码中设置
// 在代码中设置,保证不同接口的差异性
agent.timeout(5000);
// 在执行时设置参数-t 或者 -timeout
// 执行行时一次性设置,少写代码,但是不推荐
mocha -t 5000 test.js