Jest 简介 #
什么是 Jest? #
Jest 是由 Facebook(现 Meta)开发的 JavaScript 测试框架,专注于简洁性和性能。它是一个"零配置"的测试平台,开箱即用,无需复杂设置即可开始编写测试。Jest 适用于前端、后端、React、Vue、Angular 等各种 JavaScript/TypeScript 项目。
核心定位 #
text
┌─────────────────────────────────────────────────────────────┐
│ Jest │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 测试运行器 │ │ 断言库 │ │ Mock 功能 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 快照测试 │ │ 代码覆盖率 │ │ 并行执行 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Jest 的历史 #
发展历程 #
text
2014年 ─── Jest 项目启动
│
│ Facebook 内部开发
│ 专为 React 测试设计
│
2016年 ─── 开源发布
│
│ 从 React 中独立出来
│ 支持所有 JavaScript 项目
│
2017年 ─── 快照测试
│
│ 引入革命性的快照测试
│ UI 组件测试变得简单
│
2018年 ─── 性能优化
│
│ 智能并行执行
│ 增量测试
│
2020年 ─── Jest 26
│
│ 支持 TypeScript
│ 改进的 Mock 功能
│
2023年 ─── Jest 29
│
│ 更快的测试执行
│ 更好的错误消息
│
至今 ─── 行业标准
│
│ 超过 500 万周下载量
│ React 官方推荐
里程碑版本 #
| 版本 | 时间 | 重要特性 |
|---|---|---|
| 14.0 | 2016 | 开源发布,基础测试功能 |
| 18.0 | 2017 | 快照测试 |
| 22.0 | 2018 | 并行测试优化 |
| 24.0 | 2019 | 改进的 Watch 模式 |
| 26.0 | 2020 | TypeScript 支持 |
| 27.0 | 2021 | 新的测试运行器 |
| 29.0 | 2022 | 性能优化和错误改进 |
为什么选择 Jest? #
传统测试的痛点 #
在没有 Jest 之前,JavaScript 测试面临以下问题:
javascript
// 需要配置多个工具
// package.json
{
"devDependencies": {
"mocha": "^9.0.0", // 测试运行器
"chai": "^4.3.0", // 断言库
"sinon": "^12.0.0", // Mock 库
"istanbul": "^0.4.5", // 代码覆盖率
"jsdom": "^19.0.0" // DOM 模拟
}
}
// 需要编写配置文件
// karma.conf.js, mocha.opts 等
Jest 的解决方案 #
javascript
// 零配置开箱即用
// package.json
{
"devDependencies": {
"jest": "^29.0.0" // 一个包搞定所有
}
}
// 直接开始写测试
// sum.test.js
test('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
Jest 的核心特点 #
1. 零配置 #
Jest 开箱即用,无需复杂配置:
bash
# 安装
npm install --save-dev jest
# 运行测试
npx jest
# 就这么简单!
2. 快照测试 #
革命性的 UI 测试方式:
javascript
// Button.test.js
test('renders correctly', () => {
const tree = renderer.create(<Button />).toJSON();
expect(tree).toMatchSnapshot();
});
3. 并行执行 #
自动并行运行测试,充分利用多核 CPU:
text
┌─────────────────────────────────────────────────┐
│ Jest Worker Pool │
├─────────────────────────────────────────────────┤
│ Worker 1 │ Worker 2 │ Worker 3 │ Worker 4 │
│ test-a.js │ test-b.js │ test-c.js │ test-d.js│
└─────────────────────────────────────────────────┘
4. 内置代码覆盖率 #
无需额外工具:
bash
jest --coverage
# 输出详细报告
# ----------|---------|----------|---------|---------|
# File | % Stmts | % Branch | % Funcs | % Lines |
# ----------|---------|----------|---------|---------|
# All files | 90.5 | 85.2 | 92.1 | 90.5 |
# ----------|---------|----------|---------|---------|
5. 优秀的 Watch 模式 #
智能监听文件变化:
bash
jest --watch
# 只运行与修改相关的测试
# 交互式界面
# 实时反馈
6. 强大的 Mock 功能 #
内置 Mock 支持:
javascript
// 自动 Mock
jest.mock('./axios');
// 手动 Mock
const mockFn = jest.fn();
mockFn.mockReturnValue(42);
// 定时器 Mock
jest.useFakeTimers();
Jest 与其他测试框架对比 #
Jest vs Mocha #
| 特性 | Jest | Mocha |
|---|---|---|
| 零配置 | ✅ 开箱即用 | ❌ 需要配置 |
| 断言库 | ✅ 内置 | ❌ 需要 chai |
| Mock 功能 | ✅ 内置 | ❌ 需要 sinon |
| 快照测试 | ✅ 内置 | ❌ 不支持 |
| 代码覆盖率 | ✅ 内置 | ❌ 需要 istanbul |
| 并行执行 | ✅ 自动 | ⚠️ 需配置 |
Jest vs Vitest #
| 特性 | Jest | Vitest |
|---|---|---|
| 执行速度 | 快 | 更快 |
| ESM 支持 | ⚠️ 需配置 | ✅ 原生支持 |
| Vite 集成 | ❌ 无 | ✅ 原生支持 |
| 生态系统 | ✅ 成熟 | 🔄 发展中 |
| 学习资源 | ✅ 丰富 | 🔄 增长中 |
Jest vs Jasmine #
| 特性 | Jest | Jasmine |
|---|---|---|
| 零配置 | ✅ 开箱即用 | ⚠️ 需要配置 |
| Mock 功能 | ✅ 强大 | ⚠️ 基础 |
| 快照测试 | ✅ 支持 | ❌ 不支持 |
| 并行执行 | ✅ 自动 | ❌ 不支持 |
Jest 的应用场景 #
1. 单元测试 #
测试独立的函数或模块:
javascript
// math.js
export function add(a, b) {
return a + b;
}
// math.test.js
import { add } from './math';
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
2. 集成测试 #
测试多个模块协作:
javascript
// api.test.js
import { fetchUser } from './api';
test('fetches user data', async () => {
const user = await fetchUser(1);
expect(user).toHaveProperty('name');
expect(user).toHaveProperty('email');
});
3. 组件测试 #
测试 React/Vue 组件:
javascript
// Button.test.jsx
import { render, screen } from '@testing-library/react';
import Button from './Button';
test('renders button with text', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
4. 快照测试 #
确保 UI 不会意外改变:
javascript
// Header.test.jsx
import renderer from 'react-test-renderer';
import Header from './Header';
test('Header snapshot', () => {
const tree = renderer.create(<Header />).toJSON();
expect(tree).toMatchSnapshot();
});
Jest 的核心概念 #
测试结构 #
javascript
describe('Calculator', () => {
beforeAll(() => {
// 所有测试之前执行一次
});
beforeEach(() => {
// 每个测试之前执行
});
test('adds numbers', () => {
// 单个测试
});
afterEach(() => {
// 每个测试之后执行
});
afterAll(() => {
// 所有测试之后执行一次
});
});
断言 #
javascript
test('example', () => {
// 基本断言
expect(1 + 1).toBe(2);
expect(value).toEqual({ a: 1 });
expect(value).toBeTruthy();
expect(value).toContain('item');
// 否定断言
expect(value).not.toBeFalsy();
});
Mock #
javascript
// 函数 Mock
const mockCallback = jest.fn(x => 42 + x);
mockCallback(1);
expect(mockCallback).toHaveBeenCalledWith(1);
// 模块 Mock
jest.mock('./axios');
Jest 的设计哲学 #
1. 开发者体验优先 #
javascript
// 清晰的错误消息
expect(received).toBe(expected);
// Expected: 3
// Received: 2
// 详细堆栈跟踪
// at Object.<anonymous> (sum.test.js:2:10)
2. 约定优于配置 #
text
my-project/
├── src/
│ ├── sum.js
│ └── sum.test.js # 自动识别 *.test.js
├── __tests__/ # 自动识别 __tests__ 目录
│ └── sum.test.js
└── package.json
3. 性能至上 #
- 智能并行执行
- 只运行相关测试
- 增量测试缓存
Jest 的局限性 #
已知限制 #
- ESM 支持:原生 ES 模块支持需要配置
- 大型项目:测试文件很多时可能较慢
- TypeScript:需要 ts-jest 或 Babel 配置
解决方案 #
javascript
// 使用 Vitest 处理 ESM
// 使用 --onlyChanged 只运行相关测试
// 使用 --maxWorkers 控制并行度
学习路径 #
text
入门阶段
├── 安装与配置
├── 编写第一个测试
├── 使用断言
└── 测试生命周期
进阶阶段
├── 异步测试
├── Mock 功能
├── 快照测试
└── DOM 测试
高级阶段
├── 自定义配置
├── 扩展与插件
├── 性能优化
└── 调试技巧
实战阶段
├── React 测试
├── Vue 测试
├── Node.js 测试
└── 最佳实践
下一步 #
现在你已经了解了 Jest 的基本概念,接下来学习 安装与配置 开始实际使用 Jest!
最后更新:2026-03-28