Jest
安装和配置
npm i jest --save-dev
配置支持ES6
"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
生成配置文件
npx jest init
运行
// package.json
"scripts": {
"test": "jest",
"coverage": "jest --coverage" // 生成覆盖率分析文件
},
- 会自动找寻项目下.test.js文件运行测试用例
简单用法
- describe 划定作用域
- it or test 测试
- expect 预期,逻辑书写地方
- 断言 例如toBe,做一次判断
describe('test scope', () => {
it('test two', () => {
expect(1 + 6).toBe(7);
});
});
钩子函数
-
beforeEach 每个测试用例调用前都调用
-
beforeAfter 每个测试测试用例调用后都调用
-
beforeAll 仅仅在运行测试用例前运行一次
-
afterAll 仅仅在运行测试用例后运行一次
-
only 在运行测试用例时仅仅只运行这一个
适配器分类(断言)
1,常见的有toBe,判断是否相等,还有toEqual,判断值是否相等,比如对象数组这种的.
2,判断是否为真实性的适配器toBeNull是否null,toBeUndefined是否为undefined,toBeDefined是否定义了,toBeTruthy是否为真,toBefalsy是否为假.
3,数字相关类型的,toBeGreaterthan大于,toBeGreaterthanOrEqual大于等于,toBeLessthan小于,toBeLessthanOrEqual小于等于,另外还有判断小数的,由于精确度问题,所以toBe,和toEqual不能来判断小数,需要使用toBeCloseTo
4,字符串类型的可以使用toMatch来判断是否包含或者使用正则也行
5,toContain可以用来判断是否包含在数组或者对象内
6,toThrow可以用来判断是否会抛出错误
常用的就是以上这些,还有很多其他的在www.jestjs.cn/docs/expect…
异步函数的测试
运行时,消耗时间短的可以用以下方式
export const testAsyncFun = () => {
return new Promise((resolve, reject) => {
resolve(1);
});
};
describe('test', () => {
// 1,只有当传入参数done运行时,才会认为该测试用例运行完毕,所以,只需要将done运行于then中即可
it('test testAsyncFun one', done => {
testAsyncFun().then(result => {
expect(result).toBe(1);
done();
});
});
// 2,利用async与await将异步改为同步即可
it('test testAsyncFun two', async() => {
const result = await testAsyncFun();
expect(result).toBe(1);
})
});
如果,需要测试的地方运用了setTimeout,setInterval,那么就会有等待时间长的问题
// 使用假的时间
jest.useFakeTimers();
const testAsyncFun = callback => {
setTimeout(() => {
callback && callback();
}, 2000);
};
describe('test', () => {
test('test testAsyncFun', () => {
// mock一个函数,这个函数可以给我们提供信息,例如参数,返回值,调用情况
const callback = jest.fn();
testAsyncFun(callback);
// 让当前正在等待的定时器跑完
jest.runOnlyPendingTimers();
expect(callback).toHaveBeenCalledTimes(1);
});
});
- runOnlyPendingTimers,让当前正在等待的定时器跑完,没有开始的并不会跑完
- runAllTimers, 让全部的定时器跑完,没有开始的也会被执行
- advanceTimersByTime(msToRun), 让当前的时间快进,也就是设定后可以直接进行到某段时间
测试存在真实接口,可以用mock模拟替换接口
方法1:
import axios from 'axios';
import { getJsonPlaceholder } from './src/dependencies/api/ticket/create.js';
// create.js
// export const getJsonPlaceholder = () => axios.get('http://localhost:3000/user')
// mock axios
jest.mock('axios');
describe('test', () => {
it('test testAsyncFun', (done) => {
// 通过设定axios所有get返回值,既可以继续测试,不请求真实接口
axios.get.mockResolvedValue({name: 'pjm'});
getJsonPlaceholder().then(data => {
expect(data).toEqual({name: 'pjm'})
done();
})
});
});
方法2:
// 需要到模拟Mock的路径建立__mocks__文件夹,创建同名文件,之后才会在引用的时候直接引用同名方法
jest.mock('../src/dependencies/api/ticket/create');
// create mock
// export const getJsonPlaceholder = () => {
// return Promise.resolve({ name: 'pjm' });
// };
import { getJsonPlaceholder } from '../src/dependencies/api/ticket/create.js';
// 如果mock完文件后,但是有一些不想被Mock,可以通过requireActual导出
const { getJsonPlaceholder } = jest.requireActual('../src/dependencies/api/ticket/create.js');
describe('test', () => {
it('test testAsyncFun', (done) => {
getJsonPlaceholder().then(data => {
expect(data).toEqual({name: 'pjm'})
done();
})
});
});
快照
- 一般作用于配置文件,或者组件,或者成型变化少的项目
import { ticketType } from 'src/dependencies/fields/ticket/detail/detail'
// ticketType = {
// prop: 'ticket_type',
// label: '工单类型',
// type: 'select',
// enums: TicketTypeEnums,
// required: true
//}
describe('test', () => {
it('test snapshot', () => {
expect(ticketType).toMatchSnapshot();
});
});
- 通过toMatchSnapshot,第一次会生成__snapshots__文件夹,并且生成在里面添加快照文件,之后重新测试的话,会自动匹配快照文件,看是否和之前一样,不一样就报错,看是否需要更新
import { ticketType } from './config';
describe('test', () => {
it('test snapshot', () => {
expect(ticketType).toMatchInlineSnapshot(`
Object {
"enums": Array [
Object {
"id": 1,
"name": "REWORK",
"value": "返工工单",
},
Object {
"id": 2,
"name": "EXPENSE",
"value": "消耗品工单",
},
Object {
"id": 3,
"name": "ASSEMBLY",
"value": "装配件工单",
},
],
"label": "工单类型",
"prop": "ticket_type",
"required": true,
"type": "select",
}
`);
});
});
- 通过toMatchInlineSnapshot生成的快照会自动添加到参数中,不会生成新的文件来存储,但是需要配合prettier使用,所以需要安装这个先
Vue Test Utils
待续