用途
Jest 是业界标准的测试框架,据资料称拥有约 70% 的市场份额,提供成熟、经过实战检验的生态,适用于 TypeScript 项目。它可用于编写和运行单元测试、组件测试与异步测试,并生成覆盖率报告。
主要能力
- 业界标准:据资料称 70% 市场份额,被广泛采用。
- 一体化:测试运行器、断言、Mock、覆盖率集成在一个包中。
- 快照测试:内置快照支持,用于 UI 测试。
- React 集成:兼容 React Testing Library、enzyme。
- 成熟生态:丰富的插件、工具与社区支持。
- TypeScript 支持:通过 ts-jest 提供完整类型安全。
- 覆盖率报告:内置 Istanbul 覆盖率。
- 多平台:Node.js、浏览器(jsdom)、React Native。
安装
npm install -D jest @types/jest ts-jest
npm install -D @testing-library/react @testing-library/jest-dom # For React
使用方式
基础配置
初始化 Jest 配置:
npx ts-jest config:init
这会创建 jest.config.js:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
也可手动配置 jest.config.ts(TypeScript 配置):
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
collectCoverageFrom: [
'src/**/*.{ts,tsx}',
'!src/**/*.d.ts',
'!src/**/*.test.{ts,tsx}',
'!src/**/__tests__/**',
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};
export default config;
TypeScript 配置 tsconfig.json:
{
"compilerOptions": {
"types": ["jest", "@testing-library/jest-dom"],
"esModuleInterop": true
}
}
tsconfig.test.json(测试专用):
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["jest", "node", "@testing-library/jest-dom"]
},
"include": ["src/**/*.test.ts", "src/**/*.spec.ts", "src/**/__tests__/**"]
}
package.json 脚本:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:ci": "jest --ci --coverage --maxWorkers=2"
}
}
核心测试模式
基础测试结构使用 describe、it、expect、beforeEach、afterEach,并支持 it.each 参数化测试。
TypeScript 类型安全测试可对接口对象进行类型断言,例如 expect(user.id).toEqual(expect.any(Number))、expect(user).toMatchObject({...})。
Mock
- jest.mock 用于模块 Mock,配合 jest.mocked 获得类型安全的 Mock。
- jest.spyOn 用于方法监听,可 mockImplementation 提供自定义实现。
- jest.fn<FnType>() 创建类型安全的 Mock 函数。
- 定时器 Mock:jest.useFakeTimers()、jest.advanceTimersByTime()、jest.runAllTimers()、jest.clearAllTimers()。
React Testing Library + TypeScript
安装:
npm install -D @testing-library/react @testing-library/jest-dom @testing-library/user-event
npm install -D jest-environment-jsdom
React 的 jest.config.ts 使用 testEnvironment: 'jsdom',配置 setupFilesAfterEnv、moduleNameMapper 处理样式与静态资源,并通过 transform 指定 ts-jest 的 jsx: 'react-jsx'。
setup.ts 中引入 @testing-library/jest-dom 并在 afterEach 调用 cleanup。
组件测试使用 render、screen、waitFor 与 userEvent,可测试初始渲染、点击交互、回调调用、禁用状态等。
Hook 测试使用 renderHook 与 act。
异步组件测试通过 jest.mock 模拟 API,使用 waitFor 等待加载完成或错误显示。
快照测试
使用 toMatchSnapshot 或 toMatchInlineSnapshot。更新快照命令:
jest --updateSnapshot
jest -u
jest UserCard.test.tsx -u
jest --watch # 按 'u' 更新失败快照
可通过 snapshotSerializers 配置自定义快照序列化器。
异步测试
支持 async/await、rejects、resolves 匹配器,以及 done 回调方式。
覆盖率配置
jest.config.ts 中可设置 collectCoverage、coverageDirectory、coverageProvider(v8 或 babel)、coverageReporters、collectCoverageFrom、coverageThreshold(全局与按目录)、coveragePathIgnorePatterns。
运行覆盖率:
npm test -- --coverage
npm test -- --coverage --watch
npm test -- --coverage --collectCoverageFrom="src/components/**/*.tsx"
open coverage/lcov-report/index.html
从 Vitest 迁移
API 差异:Vitest 使用 vi.fn()、vi.spyOn;Jest 使用 jest.fn()、jest.spyOn。
迁移步骤:卸载 vitest 与 @vitest/ui,安装 jest、@types/jest、ts-jest;更新 package.json 脚本;用 jest.config.ts 替换 vitest.config.ts。
适用场景
- TypeScript 项目的单元测试与集成测试。
- React 组件与 Hook 测试。
- 需要快照测试的 UI 项目。
- 需要 Mock 模块、方法、定时器的测试。
- 需要覆盖率阈值与报告的项目。
- 从 Vitest 迁移到 Jest 的项目。
限制
资料未提供关于性能、价格、平台兼容性细节、已知缺陷或版本要求的具体限制说明,暂未提供。