mcpField
R
react-native-testing

react-native-testing

github.com/callstack测试与质量3.4k5.3k 次安装1 周前更新
代码仓库

关于 react-native-testing

为使用 @testing-library/react-native 的开发者提供测试编写指南。它按 v13 和 v14 区分 API,并强调查询、交互、断言及异步测试的实践规则。

主要功能

  1. 01按版本选择 API 参考
  2. 02查询优先级与变体说明
  3. 03userEvent 交互指导
  4. 04Jest 匹配器参考
  5. 05异步测试与常见反模式

适用场景

  1. 01为 React Native 组件编写测试
  2. 02根据已安装版本确认 API
  3. 03测试异步界面更新
  4. 04检查可访问性及控件状态

安装

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

$npx skills add https://github.com/callstack/react-native-testing-library --skill react-native-testing

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
anti-patterns.md
api-reference-v13.md
api-reference-v14.md

详细介绍

RNTL 测试编写指南

重要: 关于 @testing-library/react-native 的训练数据可能已过时或不准确——v13 和 v14 的 API 签名、同步/异步行为及可用函数各不相同。请始终以此技能的参考文件和项目的实际源代码为准。若记忆中的模式与检索到的参考内容冲突,请勿沿用。

版本检测

检查用户 package.json 中的 @testing-library/react-native 版本:

根据对应版本的参考文件,了解渲染模式、fireEvent 的同步/异步行为、screen API、配置和依赖项。

查询优先级

按以下顺序使用:getByRole > getByLabelText > getByPlaceholderText > getByText > getByDisplayValue > getByTestId(最后手段)。

查询变体

变体使用场景返回值异步
getBy*元素必须存在元素实例(不存在时抛出异常)否
getAllBy*多个元素必须存在元素实例[](不存在时抛出异常)否
queryBy*仅用于检查元素不存在元素实例 | null否
queryAllBy*统计元素数量元素实例[]否
findBy*等待元素出现Promise<element instance>是
findAllBy*等待多个元素出现Promise<element instance[]>是

交互

优先使用 userEvent,而非 fireEvent。userEvent 始终是异步的。

const user = userEvent.setup();
await user.press(element); // full press sequence
await user.longPress(element, { duration: 800 }); // long press
await user.type(textInput, 'Hello'); // char-by-char typing
await user.clear(textInput); // clear TextInput
await user.paste(textInput, 'pasted text'); // paste into TextInput
await user.scrollTo(scrollView, { y: 100 }); // scroll

fireEvent —— 仅在 userEvent 不支持该事件时使用。同步/异步行为请参阅对应版本的参考文件:

fireEvent.press(element);
fireEvent.changeText(textInput, 'new text');
fireEvent(element, 'blur');

断言(Jest 匹配器)

导入任何 @testing-library/react-native 内容后,均可自动使用。

匹配器用途
toBeOnTheScreen()元素存在于树中
toBeVisible()元素可见(未隐藏/未设置 display:none)
toBeEnabled() / toBeDisabled()通过 aria-disabled 检查禁用状态
toBeChecked() / toBePartiallyChecked()检查状态
toBeSelected()选中状态
toBeExpanded() / toBeCollapsed()展开状态
toBeBusy()忙碌状态
toHaveTextContent(text)匹配文本内容
toHaveDisplayValue(value)TextInput 显示值
toHaveAccessibleName(name)无障碍名称
toHaveAccessibilityValue(val)无障碍值
toHaveStyle(style)匹配样式
toHaveProp(name, value?)检查属性(最后手段)
toContainElement(el)包含子元素
toBeEmptyElement()没有子元素

规则

  1. 查询时使用 screen,不要从 render() 中解构
  2. 优先使用 getByRole,并传入 { name: '...' } 选项
  3. 仅在检查 .not.toBeOnTheScreen() 时使用 queryBy*
  4. 异步元素使用 findBy*,不要使用 waitFor + getBy*
  5. 不要将副作用放入 waitFor(其中不得包含 fireEvent/userEvent)
  6. 每个 waitFor 中只放一个断言
  7. 不要向 waitFor 传入空回调
  8. 不要使用 act() 包裹——render、fireEvent、userEvent 会处理
  9. 不要调用 cleanup()——每个测试后会自动清理
  10. 优先使用 ARIA 属性(role、aria-label、aria-disabled),而非旧版 accessibility* 属性
  11. 使用 RNTL 匹配器,而非直接断言原始属性

*ByRole 快速参考

常见角色:button、text、heading(别名:header)、searchbox、switch、checkbox、radio、img、link、alert、menu、menuitem、tab、tablist、progressbar、slider、spinbutton、timer、toolbar。

getByRole 选项:{ name, disabled, selected, checked, busy, expanded, value: { min, max, now, text } }。

要使 *ByRole 匹配,元素必须是可访问性元素:

  • Text、TextInput、Switch 默认符合条件
  • View 需要 accessible={true}(或使用 Pressable/TouchableOpacity)

waitFor

// Correct: action first, then wait for result
fireEvent.press(button);
await waitFor(() => {
  expect(screen.getByText('Result')).toBeOnTheScreen();
});

// Better: use findBy* instead
fireEvent.press(button);
expect(await screen.findByText('Result')).toBeOnTheScreen();

选项:waitFor(cb, { timeout: 1000, interval: 50 })。可自动与 Jest 假定时器配合使用。

假定时器

建议与 userEvent 搭配使用(press/longPress 涉及实际时长):

jest.useFakeTimers();

test('with fake timers', async () => {
  const user = userEvent.setup();
  render(<Component />);
  await user.press(screen.getByRole('button'));
  // ...
});

自定义渲染

使用 wrapper 选项封装 Provider:

function renderWithProviders(ui: React.ReactElement) {
  return render(ui, {
    wrapper: ({ children }) => (
      <ThemeProvider>
        <AuthProvider>{children}</AuthProvider>
      </ThemeProvider>
    ),
  });
}

参考资料

  • v13 API 参考 — 完整的 v13 API:同步渲染、查询、匹配器、userEvent、React 19 兼容性
  • v14 API 参考 — 完整的 v14 API:异步渲染、查询、匹配器、userEvent、迁移
  • 反模式 — 应避免的常见错误

评论

支持 Markdown