一、测试框架
1、Mocha
简介
相对比较新,运行在node.js上的JavaScript测试框架,可以用来做 TDD(Test-Driven Development)或 BDD(Behavior Driven Development)风格的测试。
说明:
TDD:测试驱动开发,解决的是代码级的验证,但是测试代码与需求的符合问题解决得不是很好,非技术人员、客户看不懂代码,无法评审测试是否符合需求。
BDD:行为驱动开发,理念是使用自然语言来描述功能,而且强调的是使用例子来说明需求功能。
特性
(1)全局变量泄露测试
Mocha 能够发现那种不小心创建出来的全局变量泄露,如果创建了全局变量,它会在测试时抛出错误。如果想禁用全局泄露检查,可以运行 mocha 命令时加上 --ignored-leaks 选项。
(2)用 Mocha挂钩定义设置和清理逻辑
BDD 接口 beforeEach()、afterEach()、before()和 after()接受回调,可以用来定义设置和清理逻辑。
(3)测试异步逻辑
给定义测试逻辑函数添加一个参数,就可以把 Mocha 测试用例定义为异步的。这个参数通常被命名为done
。
安装
npm install mocha
示例
describe('---------- XX管理 ----------', function () { describe('< 新增XX >', function () { it('当条件齐全时插入成功', function (done) { request.post('/XX') .set('Content-Type', 'application/json') .set('Cookie', cookie) .send({ "data": '[{' + ' "VehicleId":"1000100",' + ' "VehicleType":"面包车"' + '}]' }) .expect(200, function (err, res) { should.not.exist(err); res.text.should.containEql('"result":1'); done(); }); }); }); });
说明:
describe
块:被称为测试套件,表示一组相关的测试,它是一个函数,第一个参数是测试套件的名称,第二个参数是一个实际执行的函数。
it
块:被称为测试用例,表示一个单独的测试,是测试的最小单位,也是一个函数,第一个参数是测试用例的名字,第二个参数是一个实际执行的函数。
所有的测试用例(it块)都应该含有一句或多句断言,是编写测试用例的关键,Mocha本身不包含断言,断言是由断言库来实现的,因此需要先引入断言库。
运行测试代码
mocha默认运行test子目录里面的测试脚本,一般情况下,可以把测试脚本放在test目录下,然后进入项目对应的目录,直接执行mocha命令即可。
上面的命令只会执行test第一层目录下所有文件,并不能执行嵌套目录下的文件。为了执行所有嵌套目录下的文件,使用 mocha --recursive 。
执行test目录中的单个测试文件,使用mocha test/XXX.test.js
制作网页版报告
全局安装:
npm install -g --save-dev mochawesome
执行命令:
mocha --reporter mochawesome
说明:
1、使用上面的命令生成的报告中包含test目录下所有测试文件,若对某个测试文件生成报告在命令后加XXX.js 。
2、本地安装与全局安装
本地安装
- 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
- 可以通过 require() 来引入本地安装的包。
全局安装
- 将安装包放在 /usr/local 下或者你 node 的安装目录。
- 可以直接在命令行里使用。
2、Vows
简介
在Vows 下写的测试代码结构更加强,Vows想让测试更容易理解和维护。
按Vows 的定义,一个测试套件中包含一个或多个批次。可以把批次当做是一组相互关联的情境,或者要测试的概念领域。批次和上下文是并行运行的。上下文中可能包含主题、一个或多个誓约,以及/或者一或多个先关联的情境(内部情况也是并行运行的)。主题是跟情境相关的测试逻辑。誓约是对主题结果的测试。
套件---批次---情境 -----主题
|----誓约
|----情境
安装
npm install -g vows
示例
const vows = require('vows'); const assert = require('assert'); const Todo = require('../todo'); // 批次 vows.describe('Todo').addBatch({ // 情景 'when adding an item': { // 主题 topic: () => { const todo = new Todo(); todo.add('Feed my cat'); return todo; }, // 誓约 'it should exist in my todos': (er, todo) => { assert.equal(todo.length, 1); } } }).export(module);
二、断言库
1、assert
简介
assert模块是Node中大多数单元测试的基础,很多第三方测试框架都用到了assert模块,甚至没有测试框架也可以用它做测试。
常用断言
(1)equal:检查变量的值。
示例:
assert.equal(todo.length, 1, '1 item should exist');
(2)notEqual:找出逻辑问题。
示例:
assert.notEqual(todo.length, 0, '1 item should exist');
(3)ok:判断值是否为true。
示例:
assert.ok (value, 'Callback should be passed true');
说明:
除了 equal 和 notEqual ,assert 模块还提供了更严格的版本,strictEqual 和 notStrictEqual,它们在进行判断时用的是严格的相等操作符 ===。
assert 模块也有用来比较对象的 deepEqual 和 notEqual ,这些断言中的 deep 表明它们会层层深入对两个对象进行比较,比较两个对象的属性,如果属性也是对象,则会继续比较属性的属性。
不足:使用assert模块时,每个测试用例中都要包含很多套路化的代码用于设置测试、追踪测试进程,会占用一些时间和精力。
2、should.js
简介
是富有表现力、可读、框架无关的断言库。Should.js 跟其他框架的搭配很容易,因为它只是给 Object.prototype 增加了一个 should属性。这样你就可以写出表达能力更强的断言。
比如 user.role.should.equal('admin')或者users.should.include('rick')
安装
npm install should
常用断言
.exactly:全等,相当于===
示例:
(5).should.be.exactly(5)
.ok: 对象存在
示例:
true.should.be.ok; false.should.not.be.ok;
.true:真
示例:
(5===5).should.be.true
.eql:相等,相当于 ==
示例:
[1,2,3].should.eql([1,2,3]);
[1, 2, 3].should.eql({ '0': 1, '1': 2, '2': 3 });
说明:上面第二个例子,它们是不同的类型,但实际内容相同,这样也是正确的。
.NaN:非数字
示例:
(undefined + 0).should.be.NaN;
.typeof:判断类型
示例:
'test'.should.be.type('string');
.instanceof:构造函数的一个实例
示例:
user.should.be.an.instanceof(User);
.exist():存在
示例:
should.not.exist(err)
.containDeep():深度包含
示例:
[[1],[2],[3, 4]].should.containDeep([[3]]);
.containEql: 包含或等价于
示例:
([1, 2, { a: 10 }]).should.containEql({ a: 10 });
示例
it('当传入条件为空时修改失败', function (done) { request.post('/XX') .set('Content-Type', 'application/json') .set('Cookie', cookie) .send({ "data": null }) .expect(200, function (err, res) { should.not.exist(err); res.text.should.containEql('"result":-1'); done(); });
3、chai
简介
Chai是个流行的断言库,声明式风格更冗长,但看起来更加通顺。有三个接口:should、expect 和 assert。它还有用来比较对象、数组和它们的属性的工具。
比如用typeof
比较类型,用property
检查某个对象是否有我们想要的属性。
安装
npm install chai
示例
//引入断言库chai const chai = require('chai'); //使用它的assert断言风格 const assert = chai.assert; const foo = 'bar'; const tea = { flavors: ['char', 'earl grey', 'pg tips'] }; describe('示例',function() { it('1',function() { assert.typeOf(foo, 'string'); }); it('2',function() { assert.equal(foo, 'bar'); }); it('3',function() { assert.lengthOf(foo, 3); }); it('4',function() { assert.property(tea, 'flavors'); }); it('5',function() { assert.lengthOf(tea.flavors, 3); });
三、supertest测试库
简介
用nodejs做web开发的时候,模拟http请求时是必不可少的,当然使用浏览器也可以方便的实现http请求测试,但是并不快捷。supertest是一个非常好的适用于node的模拟http请求的库。
安装
npm install supertest
方法
.set():用来设置数据
.expect():用来断言,如:.expect(200)
.end():执行一个request请求,在回调函数里面根据业务逻辑的返回数据做断言分析。
.send():用来发送表单域数据,比如一个登录模块
.attach():主要用来测试文件上传,由于send()只能上传文本域,所以关于multipart-file的上传需要通过附件来绑定。
eg.
describe('< 上传文件 >', function () { it('条件齐全时上传成功', function (done) { request.post('/XX') .set('Content-Type', 'multipart/form-data') .set('Cookie', cookie) .field('fileId', '1000100') .attach("file","uploadFile/1.txt") .expect(200, function (err, res) { should.not.exist(err); res.text.should.containEql('"result":1'); done(); }); }); });
说明:
很多业务中,需要用户先登录才有权限执行操作,这个时候作为http请求模拟,必须要可以保存一些Cookie数据,也就是Cookie的持久化。