react-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Testing Library
React Testing Library
Test React components the way users interact with them.
以用户与组件交互的方式测试React组件。
Agent Workflow (MANDATORY)
Agent工作流程(强制要求)
Before ANY implementation, use to spawn 3 agents:
TeamCreate- fuse-ai-pilot:explore-codebase - Analyze existing test patterns
- fuse-ai-pilot:research-expert - Verify latest Testing Library docs via Context7/Exa
- mcp__context7__query-docs - Check userEvent, waitFor patterns
After implementation, run fuse-ai-pilot:sniper for validation.
在进行任何实现之前,使用生成3个Agent:
TeamCreate- fuse-ai-pilot:explore-codebase - 分析现有测试模式
- fuse-ai-pilot:research-expert - 通过Context7/Exa验证最新的Testing Library文档
- mcp__context7__query-docs - 检查userEvent、waitFor的使用模式
实现完成后,运行fuse-ai-pilot:sniper进行验证。
Overview
概述
When to Use
使用场景
- Testing React component behavior
- Validating user interactions
- Ensuring accessibility compliance
- Mocking API calls with MSW
- Testing custom hooks
- Testing React 19 features (useActionState, use())
- 测试React组件行为
- 验证用户交互
- 确保无障碍合规性
- 使用MSW模拟API调用
- 测试自定义hooks
- 测试React 19特性(useActionState、use())
Why React Testing Library
为什么选择React Testing Library
| Feature | Benefit |
|---|---|
| User-centric | Tests what users see |
| Accessible queries | Encourages a11y markup |
| No implementation details | Resilient to refactoring |
| Vitest integration | 10-20x faster than Jest |
| 特性 | 优势 |
|---|---|
| 以用户为中心 | 测试用户实际看到的内容 |
| 无障碍查询 | 鼓励编写符合a11y的标记 |
| 不关注实现细节 | 重构时更稳定 |
| 与Vitest集成 | 速度比Jest快10-20倍 |
Critical Rules
核心规则
- Query by role first - is most accessible
getByRole - Use userEvent, not fireEvent - Realistic interactions
- waitFor for async - Never
setTimeout - MSW for API mocking - Don't mock fetch
- Test behavior, not implementation - No internal state testing
- 优先按角色查询 - 是最符合无障碍标准的方式
getByRole - 使用userEvent而非fireEvent - 模拟真实的用户交互
- 异步操作使用waitFor - 绝对不要使用
setTimeout - 使用MSW模拟API - 不要直接mock fetch
- 测试行为而非实现 - 不要测试内部状态
Reference Guide
参考指南
Concepts
核心概念
| Topic | Reference |
|---|---|
| Setup & installation | |
| Query priority | |
| User interactions | |
| Async patterns | |
| API mocking | |
| React 19 hooks | |
| Accessibility | |
| Custom hooks | |
| Vitest config | |
| Mocking patterns | |
| 主题 | 参考文档 |
|---|---|
| 安装与配置 | |
| 查询优先级 | |
| 用户交互 | |
| 异步测试模式 | |
| API模拟 | |
| React 19 Hooks | |
| 无障碍测试 | |
| 自定义Hooks测试 | |
| Vitest配置 | |
| 模拟模式 | |
Templates
模板
| Template | Use Case |
|---|---|
| Vitest + RTL + MSW config |
| Simple component tests |
| Loading/error/success |
| Forms + useActionState |
| Custom hook tests |
| MSW integration tests |
| Suspense + use() |
| Error boundary tests |
| axe-core a11y audit |
| 模板 | 使用场景 |
|---|---|
| Vitest + RTL + MSW配置 |
| 简单组件测试 |
| 加载/错误/成功状态测试 |
| 表单 + useActionState测试 |
| 自定义Hook测试 |
| MSW集成测试 |
| Suspense + use()测试 |
| 错误边界测试 |
| axe-core无障碍审计 |
Forbidden Patterns
禁止使用的模式
| Pattern | Reason | Alternative |
|---|---|---|
| Not realistic | |
| Flaky | |
| Not accessible | |
| Direct fetch mocking | Hard to maintain | MSW |
Empty | No assertion | Add |
| 模式 | 原因 | 替代方案 |
|---|---|---|
| 交互不真实 | |
| 测试不稳定 | |
优先使用 | 不符合无障碍标准 | |
| 直接mock fetch | 难以维护 | MSW |
空的 | 没有断言 | 添加 |
Quick Start
快速开始
Install
安装
bash
npm install -D vitest @testing-library/react \
@testing-library/user-event @testing-library/jest-dom \
jsdom msw→ See for complete configuration
templates/basic-setup.mdbash
npm install -D vitest @testing-library/react \
@testing-library/user-event @testing-library/jest-dom \
jsdom msw→ 查看获取完整配置
templates/basic-setup.mdBasic Test
基础测试示例
typescript
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()
})→ See for more examples
templates/component-basic.mdtypescript
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.mdBest Practices
最佳实践
Query Priority
查询优先级
- - Buttons, headings, inputs
getByRole - - Form inputs
getByLabelText - - Static text
getByText - - Last resort
getByTestId
- - 按钮、标题、输入框
getByRole - - 表单输入框
getByLabelText - - 静态文本
getByText - - 最后的选择
getByTestId
Async Pattern
异步测试模式
typescript
// Preferred: findBy
await screen.findByText('Loaded')
// Alternative: waitFor
await waitFor(() => expect(...).toBeInTheDocument())→ See
templates/component-async.mdtypescript
// Preferred: findBy
await screen.findByText('Loaded')
// Alternative: waitFor
await waitFor(() => expect(...).toBeInTheDocument())→ 查看
templates/component-async.mduserEvent Setup
userEvent配置
typescript
const user = userEvent.setup()
await user.click(button)
await user.type(input, 'text')→ See
references/user-events.mdtypescript
const user = userEvent.setup()
await user.click(button)
await user.type(input, 'text')→ 查看
references/user-events.md