前端單元測試的主要框架有 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...
}
})
鉤子函數(shù)
-
before:在該區(qū)塊的所有測試用例之前執(zhí)行 -
after:在該區(qū)塊的所有測試用例之后執(zhí)行 -
beforeEach:在每個單元測試(即it)執(zhí)行前執(zhí)行 -
afterEach:在每個單元測試(即it)執(zhí)行后執(zhí)行
異步測試
-
done函數(shù)
Mocha 規(guī)定默認異步函數(shù)執(zhí)行最大時間為2000ms,如果超時則報錯,可以通過設置-timeout指定超時時長。
describe('test', function() {
it('done test', function(done) {
setTimeout(()=> {
// do something...
done()
}, 3000)
}).timeout(4000) // 設置超時時長
})
-
Promise函數(shù)
當it測試項直接返回一個Promise的時候,測試會等待Promise執(zhí)行完之后再判斷該測試是否通過。當promise執(zhí)行resolve后,測試通過;執(zhí)行reject或者都不執(zhí)行的時候,測試不通過。
describe('異步測試', function() {
it('Promise test', function() {
new Promise((resolve, reject)=> {
resolve()
})
})
})
done 方法可接收一個 Error 對象,只要 done 方法有傳遞參數(shù),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:既可以判斷對象的屬性,也可以判斷數(shù)組或字符串是否包含
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的區(qū)別是它們不會進行類型轉換,只能為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:判斷對象是否為空,或者數(shù)組、字符串長度為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 為可選,如果為數(shù)組,第一個值為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:是否包含該數(shù)組(是該數(shù)組的超集,type:Array)
expect([1, 2, 3]).to.members([2, 3])