关于 jest-skill
jest-skill 是一份使用 Jest 编写和运行 JavaScript 测试的参考技能,涵盖核心测试模式和 React 组件测试,并提供进阶实践手册。
主要功能
- 01匹配器与模拟模式
- 02异步测试示例
- 03使用 Testing Library 测试 React 组件
- 04快照测试与 Jest 命令
- 05reference/playbook.md 中的进阶模式
适用场景
- 01使用匹配器检查值和对象结果
- 02在测试中模拟函数或模块
- 03测试异步代码和 React 组件
- 04以监视模式运行测试或收集覆盖率
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ lambdatest/ agent-skills --skill jest-skill安装后在 Claude Code 中输入/jest-skill确认已加载。
附带文件reference/advanced-patterns.mdreference/playbook.md
详细介绍
Jest 测试技能
核心模式
基本测试
describe('Calculator', () => {
let calc;
beforeEach(() => { calc = new Calculator(); });
test('adds two numbers', () => {
expect(calc.add(2, 3)).toBe(5);
});
test('throws on division by zero', () => {
expect(() => calc.divide(10, 0)).toThrow('Division by zero');
});
});
匹配器
expect(value).toBe(exact); // === strict
expect(value).toEqual(object); // deep equality
expect(value).toBeTruthy();
expect(value).toBeNull();
expect(value).toBeGreaterThan(3);
expect(value).toBeCloseTo(0.3, 5);
expect(str).toMatch(/regex/);
expect(arr).toContain(item);
expect(arr).toHaveLength(3);
expect(obj).toHaveProperty('name');
expect(obj).toMatchObject({ name: 'Alice' });
expect(() => fn()).toThrow(CustomError);
模拟
// Mock function
const mockFn = jest.fn();
mockFn.mockReturnValue(42);
mockFn.mockResolvedValue({ data: 'test' });
expect(mockFn).toHaveBeenCalledWith('arg1');
expect(mockFn).toHaveBeenCalledTimes(1);
// Mock module
jest.mock('./database');
const db = require('./database');
db.getUser.mockResolvedValue({ name: 'Alice' });
// Mock with implementation
jest.mock('./api', () => ({
fetchUsers: jest.fn().mockResolvedValue([{ name: 'Alice' }]),
}));
// Spy
const spy = jest.spyOn(console, 'log').mockImplementation();
expect(spy).toHaveBeenCalledWith('expected');
spy.mockRestore();
// Fake timers
jest.useFakeTimers();
jest.advanceTimersByTime(1000);
jest.useRealTimers();
异步测试
test('fetches users', async () => {
const users = await fetchUsers();
expect(users).toHaveLength(3);
});
test('resolves with data', () => {
return expect(fetchData()).resolves.toEqual({ data: 'value' });
});
test('rejects with error', () => {
return expect(fetchBadData()).rejects.toThrow('not found');
});
React 组件测试(Testing Library)
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import LoginForm from './LoginForm';
test('submits login form', async () => {
const onSubmit = jest.fn();
render(<LoginForm onSubmit={onSubmit} />);
fireEvent.change(screen.getByLabelText('Email'), {
target: { value: '[email protected]' },
});
fireEvent.change(screen.getByLabelText('Password'), {
target: { value: 'password123' },
});
fireEvent.click(screen.getByRole('button', { name: /login/i }));
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith({
email: '[email protected]', password: 'password123',
});
});
});
快照测试
test('renders correctly', () => {
const tree = renderer.create(<Button label="Click" />).toJSON();
expect(tree).toMatchSnapshot();
});
// Update: jest --updateSnapshot
反模式
| 不佳做法 | 良好做法 | 原因 |
|---|---|---|
expect(x === y).toBe(true) | expect(x).toBe(y) | 错误提示更好 |
异步操作不使用 await | 始终使用 await | 会吞掉失败 |
| 对所有内容都做快照 | 对 UI 做快照,对逻辑做断言 | 快照疲劳 |
快速参考
| 任务 | 命令 |
|---|---|
| 运行全部测试 | npx jest |
| 监听模式 | npx jest --watch |
| 覆盖率 | npx jest --coverage |
| 更新快照 | npx jest --updateSnapshot |
| 运行文件 | npx jest tests/calc.test.js |
| 单个测试 | test.only('name', () => {}) |
深入模式
有关适用于生产环境的模式,请参阅 reference/playbook.md:
| 章节 | 内容 |
|---|---|
| §1 生产环境配置 | Node + React 配置、路径别名、覆盖率阈值 |
| §2 模拟深入解析 | 模块/部分/手动模拟、间谍、计时器、环境变量 |
| §3 异步模式 | Promise、拒绝、事件发射器、流 |
| §4 test.each | 用于表驱动测试的数组、标记模板、describe.each |
| §5 自定义匹配器 | toBeWithinRange、toBeValidEmail、TypeScript 声明 |
| §6 React Testing Library | userEvent、钩子、上下文提供程序 |
| §7 快照测试 | 组件、内联、属性匹配器 |
| §8 API 服务测试 | 模拟 axios、CRUD 模式、错误处理 |
| §9 全局设置 | 多项目配置、数据库设置/清理 |
| §10 CI/CD | 带覆盖率门槛的 GitHub Actions |
| §11 调试表 | 10 个常见问题及其修复方法 |
| §12 最佳实践 | 15 项生产环境检查清单 |
评论
支持 Markdown