mcpField
R
react-testing

react-testing

github.com/fusengine测试与质量3442 次安装2 周前更新
代码仓库

关于 react-testing

面向 React 组件测试的实用方法技能,使用 Testing Library、Vitest 和 MSW,强调按用户行为及可访问性测试,而非内部实现。覆盖 React 19 特性、异步测试和 9 个可复用模板。

主要功能

  1. 01优先使用可访问性查询
  2. 02用 userEvent 模拟交互
  3. 03用 findBy 和 waitFor 断言异步行为
  4. 04使用 MSW 模拟 API
  5. 05测试 React 19、Hook 与边界组件
  6. 06提供 9 个测试模板

适用场景

  1. 01验证组件交互行为
  2. 02测试异步加载、错误与成功状态
  3. 03测试表单和自定义 Hook
  4. 04检查可访问性并测试 API 集成

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fusengine/claude-plugins --skill react-testing

安装后在 Claude Code 中输入/react-testing确认已加载。

详细介绍

使用 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:

  1. fuse-ai-pilot:explore-codebase - 分析现有测试模式
  2. fuse-ai-pilot:research-expert - 通过 Context7/Exa 验证最新的 Testing Library 文档
  3. 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 倍

关键规则

  1. 优先按角色查询 - getByRole 的可访问性最佳
  2. 使用 userEvent,不要使用 fireEvent - 实现真实的交互
  3. 异步操作使用 waitFor - 绝不使用 setTimeout
  4. 使用 MSW 模拟 API - 不要模拟 fetch
  5. 测试行为,而非实现 - 不测试内部状态

参考指南

概念
主题参考资料
设置与安装references/installation.md
查询优先级references/queries.md
用户交互references/user-events.md
异步模式references/async-testing.md
API 模拟references/msw-setup.md
React 19 Hookreferences/react-19-hooks.md
可访问性references/accessibility-testing.md
自定义 Hookreferences/hooks-testing.md
Vitest 配置references/vitest-config.md
模拟模式references/mocking-patterns.md
模板
模板使用场景
templates/basic-setup.mdVitest + RTL + MSW 配置
templates/component-basic.md简单组件测试
templates/component-async.md加载/错误/成功状态
templates/form-testing.md表单 + useActionState
templates/hook-basic.md自定义 Hook 测试
templates/api-integration.mdMSW 集成测试
templates/suspense-testing.mdSuspense + use()
templates/error-boundary.md错误边界测试
templates/accessibility-audit.mdaxe-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


最佳实践

查询优先级
  1. getByRole - 按钮、标题、输入框
  2. getByLabelText - 表单输入框
  3. getByText - 静态文本
  4. 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