环境搭建
- 生成
package.json,执行npm init -y - 下载
jest,执行yarn add jest --dev
最基本的测试
-
创建被测试的文件以及方法,比如创建:
index.jsfunction sum(a, b) { return a + b; } module.exports = { sum } -
创建测试文件,比如:
index.test.jsconst {sum} = require('./index.js'); test('sum_test', ()=>{ expect(sum(2,2)).toBe(3); }) /** * test('测试说明', ()=>{ * expect(被测试的内容).匹配器 * }) */ -
修改
package.json的test指令:{ "scripts": { "test": "jest" } } -
执行
yarn test,查看结果。
测试覆盖率生成
代码覆盖率含义:测试时执行的代码占所有源代码的比例
-
生成基础配置文件:
npx jest --init,生成时会有一些选项如下:- Would you like to use Typescript for the configuration file? —— 是否对配置文件使用ts
- Choose the test environment that will be used for testing —— 选择测试的测试环境(node或者浏览器环境)
- Do you want Jest to add coverage reports? —— 是否生成代码覆盖率报告
- Which provider should be used to instrument code for coverage? —— 选择代码覆盖率标准的厂家(v8或者babel)
- Automatically clear mock calls, instances and results before every test? —— 在每次测试之前自动清除模拟调用、实例和结果
-
选择之后,就可以在项目根目录中看见
jest.config.js,以上的问题可以通过配置文件来修改 -
修改配置文件中的
collectCoverage为true。(如果上面问题已经选择生成覆盖率可以不改) -
执行
npx jest --coverage来查看代码覆盖率信息: -
同时,在根目录中会生成一个
coverage文件。里面是代码覆盖率信息的文件。可以打开其中的lcov-report/index.html查看
常用的匹配器
toBe()匹配器toBe()匹配器类似
===,会比较结果是不是绝对等于test('toBe()匹配器', ()=>{ expect('test').toBe('test'); }) // 测试不通过 test('toBe()匹配器2', ()=>{ const obj = {name:'zs'}; expect(obj).toBe({name:'zs'}); })toEqual()匹配器toEqual()只是比较想等,类似于==test('toEqual()匹配器', ()=>{ expect('test').toEqual('test'); }) test('toEqual()匹配器2', ()=>{ const obj = {name:'zs'}; expect(obj).toEqual({name:'zs'}); })toBeNull()匹配器toBeNull()匹配器是只有返回值为null时才通过匹配.test('toBeNull()匹配器', ()=>{ const a = null; expect(a).toBeNull(); }) // undefined也不可以通过测试! test('toBeNull()匹配器2', ()=>{ let a; expect(a).toBeNull(); })toBeUndefined()匹配器toBeUndefined()匹配器,只有当返回值为undefined时才可以通过// 测试不通过,值为null test('toBeUndefined()匹配器', ()=>{ const a = null; expect(a).toBeUndefined(); }) test('toBeUndefined()匹配器2', ()=>{ let a; expect(a).toBeUndefined(); })toBeDefined()匹配器toBeDefined()匹配器,只要值定义过就可以通过test('toBeDefined()匹配器', ()=>{ const a = null; expect(a).toBeDefined(); }) test('toBeDefined()匹配器2', ()=>{ let a = '111'; expect(a).toBeDefined(); })toBeTruThy()匹配器和toBeFalsy()匹配器toBeTruThy()匹配器是只要为true就通过测试,toBeFalsy()匹配器则为false就通过test('toBeTruthy()匹配器', ()=>{ const a = '111'; expect(a).toBeTruthy(); }) test('toBeFalsy()匹配器', ()=>{ let a = null; expect(a).toBeFalsy(); })toBeGreaterThan()匹配器和toBeGreaterThanOrEqual()匹配器toBeGreaterThan()匹配器用来和数字做比较,可以理解成大于>,而toBeGreaterOrEqual()则可以理解成大于等于>=test('toBeGreaterThan()匹配器', ()=>{ const num = 10; expect(num).toBeGreaterThan(9); })toBeLessThan()匹配器和toBeLessThanOrEqual()匹配器toBeLessThan()匹配器可以理解是小于<,而toBeLessThanOrEqual()则是小雨等于test('toBeLessThan()匹配器', ()=>{ const num = 10; expect(num).toBeLessThan(11); })toBeCloseTo()匹配器toBeCloseTo()匹配器可以自动消除js浮点精确度错误。// 测试不通过 test('toBeEqual', ()=>{ expect(0.1+0.2).toEqual(0.3); }) test('toBeCloseTo()匹配器', ()=>{ expect(0.1+0.2).toBeCloseTo(0.3); })toMatch()匹配器toMatch()匹配器,类似于includes,判断字符串是否包含指定内容test('toMatch()匹配器', ()=>{ const str = '苹果、柿子、鸭梨、葡萄'; expect(str).toMatch('柿子2'); })toContain()匹配器toContain()匹配器类也是类似于includes,只是它用于数组和Settest('toContain()匹配器', ()=>{ const arr = ['苹果','柿子','鸭梨',"葡萄"]; expect(arr).toContain('柿子'); }) test('toContain()匹配器2', ()=>{ const arr = ['苹果','柿子','鸭梨',"葡萄"]; const set = new Set(arr); expect(set).toContain('柿子'); })toThrow()匹配器toThrow()匹配器,只要抛出异常,就通过测试test('toThrow()匹配器', ()=>{ const fn = ()=>{ throw new Error('error'); } expect(fn).toThrow(); }) // 如果匹配器传入字符串,异常内容必须和字符串一致才可以通过测试 test('toThrow()匹配器2', ()=>{ const fn = ()=>{ throw new Error('error'); } expect(fn).toThrow('error'); })not()匹配器
not()匹配器可以理解成取反的意思!。not()匹配器可以和其他匹配器一块使用
// 只要内容不是test就可以通过测试
test('not()匹配器', ()=>{
expect('testaaa').not.toBe('test');
})
异步测试方法
- 回调函数测试
// 被测试方法
function fetchData(callback){
setTimeout(()=>{
callback({msg:'error'})
},1500)
}
// jest测试部分
test('fetchData_test', ()=>{
fetchData((data)=>{
expect(data).toEqual({msg:'ok'})
})
})
上面的写法是无论执行成功和失败都是可以通过测试的,因为当执行测试的时候。代码还没有执行完毕。回调还没有执行,所以需要加入一个done方法来保证执行。jest修改为如下内容:
test('fetchData_test', (done)=>{
fetchData((data)=>{
expect(data).toEqual({msg:'ok'});
done();
})
})
done函数如果一直没有执行,就会认为是测试失败。显示超时错误
- Promise测试
// 被测试方法
function fetchData(){
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve({msg:'ok'})
},1500)
})
}
//jest 测试部分
test('promise_test', ()=>{
return fetchData().then(data=>{
expect(data).toEqual({msg:'ok'})
})
})
3.Async/Await测试
test('async-await_test', async ()=>{
const data = await fetchData();
expect(data).toEqual({msg:'ok'})
})