一.是什么?
Jest是Facebook开源的一个前端测试框架,自动集成了断言、JSdom、覆盖率报告等,内部也是使用了jasmine作为基础,在其上进行了封装。主要用于React和React Native的单元测试,已被集成在create-react-app中。
二.特点
- 速度快:支持并行执行,Jest 为每一个单元测试文件创造一个独立的运行环境。Jest 可以启动多个进程同时运行不同的文件,充分利用多核CPU。单进程 100 秒才完成的测试执行过程,8 核只需要 12.5 秒。并且可以通过test.only这种语法只运行特定的测试用例。
- 易配置:虽然号称0配置,但在真实的项目中,还是要根据具体需求,进行配置。
- IDE整合:配合vscode中的jest插件,编写完测试用例后,IDE自动运行测试用例。
- Snapshot:Jest能够对React组件树进行序列化,生成对应的字符串快照,通过比较字符串提供高性能的UI检测。
- 多项目并行:可以同时跑React和node的测试用例。
- 覆盖率:内置Istanbul,测试代码覆盖率,并生成对应的报告
- Mock系统:Jest实现了一个强大的Mock系统,支持自动和手动mock。
三.实现原理
通过对比预期和实际结果进行测试。
假如我们有一个这样的函数需要测试,如下:
function add(a, b) {
return a + b
}
是的,只是计算传入参数之和,并返回。
测试代码如下(模拟Jest内部实现)
function expect(result) {
return {
toBe: function(actual) {
if(result !== actual) {
throw new Error(`预期值和实际值不相等 预期${actual} 实际结果却是${result}`)
}
}
}
}
function test(desc, fn) {
try {
fn();
console.log(`${desc} 通过测试`)
}catch(e) {
console.log(`${desc} 没有通过测试 ${e}`)
}
}
test("测试加法 1 + 1 是否等于 2", () => {
expect(add(1, 1)).toBe(2);
})
四.生命周期函数
- beforeAll(fn):所有测试用例执行之前执行的方法。
- beforeEach(fn):每个测试用例执行之前执行的方法。
- afterEach(fn):每个测试用例执行之后执行的方法。
- afterAll(fn):所有测试用例执行之后执行的方法。
全局和describe都可以有这四个生命周期函数。
一个demo说明他们的执行顺序:
export default class Counter {
constructor() {
this.number = 0;
}
addOne() {
this.number += 1;
}
minusOne() {
this.number -= 1;
}
}
// 测试代码
import Counter from './Counter';
describe("测试 Counter", () => {
let counter = null;
console.log("第一层describe");
beforeAll(() => {
console.log("beforeAll");
})
beforeEach(() => {
console.log("beforeEach");
counter = new Counter();
})
afterEach(() => {
console.log("afterEach");
})