React 组件如何进行测试?
一、是什么
React 测试是指通过自动化的方式验证组件的行为是否符合预期。现代 React 测试的核心理念是 "测试用户行为,而非实现细节"——关注组件渲染了什么、用户交互后发生了什么,而不是内部 state 如何变化。
测试金字塔在 React 中的体现:
标准技术栈:Jest(测试运行器)+ React Testing Library(组件测试工具)+ user-event(用户交互模拟)。
二、React Testing Library 基础
渲染与查询
React Testing Library(RTL)的核心 API 是 render 和 screen:
查询方法优先级
RTL 提供三种查询变体,各有用途:
按语义化优先级选择查询方法:
getByRole 是首选方案,因为它与用户和辅助技术感知页面的方式一致。
三、用户交互测试
使用 @testing-library/user-event 模拟真实用户操作,比底层的 fireEvent 更贴近真实行为:
userEvent 与 fireEvent 的区别:userEvent 会模拟完整的事件序列(如 type 会触发 focus → keyDown → keyPress → input → keyUp),更接近真实用户操作。
四、异步测试
waitFor 等待状态更新
findBy 异步查询
findBy 内部封装了 waitFor,是等待异步元素出现的简洁写法:
五、Mock 技术
Jest Mock
MSW(Mock Service Worker)
MSW 在网络层拦截请求,比 mock 模块更接近真实场景:
MSW 的优势:mock 对组件代码透明,不需要修改 import 或注入依赖,且同一套 handler 可在开发、测试、Storybook 中复用。
六、测试 Hooks
使用 renderHook 独立测试 Custom Hook:
七、快照测试
快照测试捕获组件的渲染输出,检测意外变化:
快照测试的利弊:
建议:仅对稳定的基础组件使用快照测试,业务组件优先写行为测试。
八、E2E 测试
端到端测试验证完整的用户流程,Playwright 是目前主流选择:
E2E 测试选型对比:
九、测试最佳实践
核心原则
- 测行为不测实现:不要断言 state 值,断言渲染结果和副作用
- 每个测试独立:不依赖其他测试的执行顺序
- 使用语义化查询:优先
getByRole、getByLabelText,避免依赖 CSS 类名 - 避免过度 mock:只 mock 外部依赖,组件内部逻辑真实执行
- 测试边界情况:空数据、加载状态、错误状态
十、总结
核心理念:以用户视角编写测试,关注 "组件做了什么" 而非 "组件怎么做的",让测试成为重构的安全网而非束缚。