关于 react-testing
为 React 19 组件测试提供方法指南,适用于使用 Testing Library 和 Vitest 的开发者。内容涵盖用户行为、异步断言、API 模拟及可访问性,并提供配置和测试模板。
主要功能
- 01优先使用可访问性查询
- 02用 userEvent 模拟交互
- 03用 findBy 和 waitFor 处理异步
- 04用 MSW 模拟 API
- 05覆盖 React 19 与边界测试
- 06提供 Vitest 配置和 9 个模板
适用场景
- 01验证组件的用户交互
- 02测试自定义 Hook 与 React 19 特性
- 03检查可访问性并模拟 API 调用
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fusengine/ agents --skill react-testing安装后在 Claude Code 中输入/react-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/accessibility-testing.mdasync-testing.mdhooks-testing.mdinstallation.mdmocking-patterns.mdmsw-setup.mdqueries.mdreact-19-hooks.mduser-events.mdvitest-config.mdreferences/templates/accessibility-audit.mdapi-integration.mdbasic-setup.mdcomponent-async.mdcomponent-basic.mderror-boundary.mdform-testing.mdhook-basic.mdsuspense-testing.md详细介绍
使用 Testing Library 和 Vitest 测试 React 19 组件:优先使用以用户为中心的查询,并按可访问性排序(先用 `getByRole`,最后才考虑 `getByTestId`);使用 `userEvent` 实现真实的交互(绝不使用 `fireEvent`);使用 `findBy`/`waitFor` 进行异步断言(绝不使用 `setTimeout`);使用 MSW 模拟 API(绝不直接模拟 fetch)。
还涵盖 React 19 功能(useActionState、use())、自定义 Hook、Suspense 边界、错误边界,以及使用 axe-core 进行的可访问性审查。提供 Vitest 配置和 9 个可直接复制的测试模板。这是一项构建在 React 技能(react-19、react-state、react-forms)之上的测试方法技能——它不讲解这些 API 本身,只讲解如何测试使用这些 API 的组件。
React Testing Library
按照用户与组件交互的方式测试 React 组件。
Agent 工作流(必须遵守)
在进行任何实现之前,必须并行启动 3 个 Agent,每个 Agent 调用都要指定一个 name:
- fuse-ai-pilot:explore-codebase - 分析现有测试模式
- fuse-ai-pilot:research-expert - 通过 Context7/Exa 验证最新的 Testing Library 文档
- mcp__context7__query-docs - 检查 userEvent、waitFor 模式
实现完成后,运行 fuse-ai-pilot:sniper 进行验证。
概览
适用场景
- 测试 React 组件行为
- 验证用户交互
- 确保符合可访问性要求
- 使用 MSW 模拟 API 调用
- 测试自定义 Hook
- 测试 React 19 功能(useActionState、use())
为什么选择 React Testing Library
| 功能 | 优点 |
|---|---|
| 以用户为中心 | 测试用户能看到的内容 |
| 可访问性查询 | 鼓励使用符合 a11y 标准的标记 |
| 不依赖实现细节 | 重构后依然稳健 |
| Vitest 集成 | 速度比 Jest 快 10-20 倍 |
关键规则
- 优先按角色查询 -
getByRole的可访问性最佳 - 使用 userEvent,不要使用 fireEvent - 实现真实的交互
- 异步操作使用 waitFor - 绝不使用
setTimeout - 使用 MSW 模拟 API - 不要模拟 fetch
- 测试行为,而非实现 - 不测试内部状态
参考指南
概念
| 主题 | 参考资料 |
|---|---|
| 设置与安装 | references/installation.md |
| 查询优先级 | references/queries.md |
| 用户交互 | references/user-events.md |
| 异步模式 | references/async-testing.md |
| API 模拟 | references/msw-setup.md |
| React 19 Hook | references/react-19-hooks.md |
| 可访问性 | references/accessibility-testing.md |
| 自定义 Hook | references/hooks-testing.md |
| Vitest 配置 | references/vitest-config.md |
| 模拟模式 | references/mocking-patterns.md |
模板
| 模板 | 使用场景 |
|---|---|
templates/basic-setup.md | Vitest + RTL + MSW 配置 |
templates/component-basic.md | 简单组件测试 |
templates/component-async.md | 加载/错误/成功状态 |
templates/form-testing.md | 表单 + useActionState |
templates/hook-basic.md | 自定义 Hook 测试 |
templates/api-integration.md | MSW 集成测试 |
templates/suspense-testing.md | Suspense + use() |
templates/error-boundary.md | 错误边界测试 |
templates/accessibility-audit.md | axe-core a11y 审查 |
禁止的模式
| 模式 | 原因 | 替代方案 |
|---|---|---|
fireEvent | 不够真实 | userEvent |
setTimeout | 容易不稳定 | waitFor、findBy |
首先使用 getByTestId | 不符合可访问性要求 | getByRole |
| 直接模拟 fetch | 难以维护 | MSW |
空的 waitFor | 没有断言 | 添加 expect() |
快速开始
安装
npm install -D vitest @testing-library/react \
@testing-library/user-event @testing-library/jest-dom \
jsdom msw
→ 完整配置请参阅 templates/basic-setup.md
基础测试
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
test('button click works', async () => {
const user = userEvent.setup()
render(<Button onClick={fn}>Click</Button>)
await user.click(screen.getByRole('button'))
expect(fn).toHaveBeenCalled()
})
→ 更多示例请参阅 templates/component-basic.md
最佳实践
查询优先级
getByRole- 按钮、标题、输入框getByLabelText- 表单输入框getByText- 静态文本getByTestId- 最后才考虑
Async Pattern
// Preferred: findBy
await screen.findByText('Loaded')
// Alternative: waitFor
await waitFor(() => expect(...).toBeInTheDocument())
→ See templates/component-async.md
userEvent Setup
const user = userEvent.setup()
await user.click(button)
await user.type(input, 'text')
→ See references/user-events.md
评论
支持 Markdown