前端单元测试的主要框架有 Mocha 和 Jasmine,断言库有 should、 chai、expect 以及node自带的 assert。这里主要讲解 Mocha 框架和 chai 断言。
Mocha 框架
- describe('name', fn) 定义一组测试
- it('name', fn) 定义一项测试
// 定义一组测试
describe('test-1', function() {
// 定义第一项测试
it('test-1-1', function() {
//do something...
}
// 定义第二项测试
it('test-1-2', function() {
//do something...
}
})
钩子函数
-
before
:在该区块的所有测试用例之前执行 -
after
:在该区块的所有测试用例之后执行 -
beforeEach
:在每个单元测试(即it)执行前执行 -
afterEach
:在每个单元测试(即it)执行后执行
异步测试
-
done
函数
Mocha 规定默认异步函数执行最大时间为2000ms,如果超时则报错,可以通过设置-timeout
指定超时时长。
describe('test', function() {
it('done test', function(done) {
setTimeout(()=> {
// do something...
done()
}, 3000)
}).timeout(4000) // 设置超时时长
})
-
Promise
函数
当it
测试项直接返回一个Promise
的时候,测试会等待Promise
执行完之后再判断该测试是否通过。当promise执行resolve
后,测试通过;执行reject
或者都不执行的时候,测试不通过。
describe('异步测试', function() {
it('Promise test', function() {
new Promise((resolve, reject)=> {
resolve()
})
})
})
done 方法可接收一个 Error 对象,只要 done 方法有传递参数,Mocha就会视为测试不通过。
chai.js 断言库
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
上面部分api没有任何意义,只是为了提高可读性。
- not:去之后的断言相反
expect(1).to.not.equal(2);
- deep:深度递归比较对象的值
expect({a: {num: 1}}).to.deep.equal({a: {num: 1}})
- any:在keys断言前使用,包含任意一个或多个
expect({name: 'chai'}).to.any.keys('name', 'age')
- all:在keys断言前使用,包含全部
expect({name: 'chai', age: '1'}).to.all.keys('name', 'age')
- a/an:判断值的类型
expect(1).to.a('number')
- include/contains:既可以判断对象的属性,也可以判断数组或字符串是否包含
expect({name: 'chai', age: 1}).to.include('name')
expect([1,2,3]).to.include(2)
- ok:判断是否为真值
expect('123').to.be.ok
expect(false).to.not.be.ok
- true/false:判断目标的值,与.ok的区别是它们不会进行类型转换,只能为true/false
expect(2>1).to.be.true
expect(1>2).to.be.false
- null/undefined/NaN:判断目标是否等于 null/undefined/NaN
expect(null).to.be.null
expect(undefined).to.be.undefined
expect('chai').to.be.NaN
- exist:判断目标是否存在,既非 null 也非 undefined
expect(null).to.not.exist
expect('a').to.exist
- empty:判断对象是否为空,或者数组、字符串长度为0
expect([]).to.empty
expect({}).to.empty
- equal:判断是否严格等于(
===
)
expect(1).to.equal(1)
- eql:相当于.deep.equal
expect({name: 'chai'}).to.eql({name: 'chai')
- above:大于
- least:大于或等于
- below:小于
- most:小于或等于
expect(10).to.above(5)
expect(10).to.least(10)
expect(10).to.below(15)
expect(10).to.most(10)
- within(number, number):设置上下限
expect(10).to.within(10, 20)
- property(key, value):判断是否包含该属性,value 为可选,如果为数组,第一个值为index,第二个值为value
expect({name: 'chai'}).to.property('name')
expect({name: 'chai'}).to.property('name', 'chai')
expect([1, 2, 3, 4]).to.property('[1]', 2)
- ownProperty:自身是否包含的属性
expect([]).to.ownProperty('length')
- length:长度是否相等
expect([1, 2, 3]).length(3)
- match:匹配正则表达式
expect('chai.js').to.match(/chai/)
- string:是否包含另外一个字符串
expect('chai.js').string('chai')
- keys:目标包含的属性,可与
.any
、.all
等配合使用
expect({name: 'chai', age: 1}).to.any.keys('name')
- closeTo(number, range):设置前后误差范围
expect(1.5),to.closeTo(1, 1)
- members:是否包含该数组(是该数组的超集,type:Array)
expect([1, 2, 3]).to.members([2, 3])
网友评论