前端工具优化测试Jest 快速入门
Kaede什么是 Jest

Jest 是一个前端单元测试框架, 由 Facebook 退出, 是目前前端最火热的框架. 它具有以下特点:
- Fast 天下武功, 唯快不破
- Opinionated 开箱即用
- Watch Mode 守护模式
- Shapshot Testing 快照测试
基础使用
这里首先创建一个前端项目, 这里直接 yarn init 一个出来.
随后, 在项目中安装 jest:
这里从一个最简单的函数开始, 直接创建一个 math.js 工具文件出来, 并且写入以下代码:
1 2 3
| const mySum = (a, b) => a + b
export {mySum}
|
随后就可以创建测试文件了. 测试文件需要使用 .test.js 结尾. 一般来说, 我们创建 文件名.test.js.
1 2 3 4 5 6 7
| const mySum = require('./math')
test("这里写描述信息, 用来测试1 + 2 = 3", () => { expect(mySum(1, 2)).toBe(3) })
|
随后, 我们可以添加一个命令, 来运行 jest:
1 2 3 4 5 6 7 8 9 10 11 12
| { "name": "jest-study", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "test": "jest" }, "devDependencies": { "jest": "^30.0.5" } }
|
随后, 直接运行 yarn test 就可以看到效果了:
1 2 3 4 5 6 7 8 9 10
| $ jest PASS ./math.test.js √ 这里写描述信息, 用来测试1 + 2 = 3 (3 ms)
Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 0.396 s Ran all test suites. Done in 1.47s.
|
这里会显示绿色的 passed, 就保证了 sum 函数符合预期. 假如后面函数改错了, 改没了, 那么就会出现失败的情况, 可以看到没有通过的报错信息是什么, 方便我们定位问题.
判断方法
jest 最核心的就是后面的 toBe 之类的判断方法, 不过不止这些, 还有更多的内容.
toBe
这个是严格相等, 对于普通的字符串, 数字, 布尔值可以这么判断, 但是如果是数组, 则不能这么写. 例如下面写一个返回值为函数的代码.
1 2 3 4 5
| function addToArr(arr, ...args) { arr.push(...args) }
module.exports = addToArr
|
对应的测试文件如下:
1 2 3 4 5 6 7
| const addToArr = require('./addToArr')
test("添加4, 5, 6到数组 [1, 2, 3]中", () => { const arr = [1, 2, 3] addToArr(arr, 4, 5, 6) expect(arr).toBe([1, 2, 3, 4, 5, 6]) })
|
毫无疑问的 failed 了:

这里的解释其实也写了, 应该深层次的比较. 所以我们这里要用别的.
toEqual
为了解决上面数组无法比较的问题, 我们需要引入 toEqual 进行深层次的拷贝. 上面的代码改成下面这样, 即可通过测试.
1 2 3 4 5 6 7
| const addToArr = require('./addToArr')
test("添加4, 5, 6到数组 [1, 2, 3]中", () => { const arr = [1, 2, 3] addToArr(arr, 4, 5, 6) expect(arr).toEqual([1, 2, 3, 4, 5, 6]) })
|
这就是 toEqual 的用法.
not
其实就是顾名思义, 不等于. 还是上面的代码, 通过 .not.toBe, 就可以通过测试了.
1 2 3 4 5 6 7
| const addToArr = require('./addToArr')
test("添加4, 5, 6到数组 [1, 2, 3]中", () => { const arr = [1, 2, 3] addToArr(arr, 4, 5, 6) expect(arr).not.toBe([1, 2, 3, 4, 5, 6]) })
|
这里仅仅作为演示, 我们不推荐这样进行判断.
更多方法
mockFn
无论如何, 我们的函数不一定会返回, 我们可能只希望看看一个函数运行是否正常, 运行次数是否为期待的期数.
例如下面这个, 对 map 进行一个包装:
1 2 3 4 5
| function map(arr, cb) { return arr.map(cb) }
module.exports = map
|
这里的测试就需要用到 mock 了.
1 2 3 4 5 6 7 8
| const map = require('./map')
test("map [1, 2, 3], 回调函数执行三次", () => { const mockFn = jest.fn(x => x * 2) map([1, 2, 3], mockFn) expect(mockFn.mock.calls.length).toBe(3) })
|
另外, 如果需要测试别的, 也可以继续往后写:
1 2 3 4 5 6 7 8 9 10 11 12
| const map = require('./map')
test("map [1, 2, 3], 回调函数执行三次", () => { const mockFn = jest.fn(x => x * 2) map([1, 2, 3], mockFn) expect(mockFn.mock.calls.length).toBe(3) expect(mockFn.mock.results[0].value).toBe(2) expect(mockFn.mock.results[1].value).toBe(4) expect(mockFn.mock.results[2].value).toBe(6) })
|
分组
一个文件有很多测试的话, 我们可以使用 describe 进行一个分组.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const map = require('./map')
describe('测试map函数是否运行正常', () => { test("map [1, 2, 3], 回调函数执行三次", () => { const mockFn = jest.fn(x => x * 2) map([1, 2, 3], mockFn) expect(mockFn.mock.calls.length).toBe(3) })
test("map [1, 2, 3], 回调结果正常", () => { const mockFn = jest.fn(x => x * 2) map([1, 2, 3], mockFn) expect(mockFn.mock.results[0].value).toBe(2) expect(mockFn.mock.results[1].value).toBe(4) expect(mockFn.mock.results[2].value).toBe(6) }) });
|
再次运行, 就可以看到已经将测试进行分组了.
测试覆盖率
可以在执行 jest 命令的时候, 后面加上一个参数, 用来生成测试覆盖率的情况.
1 2 3 4 5
| { "scripts": { "test": "jest --coverage" }, }
|
再次运行 test, 就可以看到生成的表格了.

另外, 也会生成一个 coverage 目录, 这个目录存放的就是网页版的覆盖率图了, 可以直接打开看看:

还是十分专业的.