Loading...
Loading...
Compare original and translation side by side
@testing-library/react-native@testing-library/react-native@testing-library/react-nativepackage.jsontest-rendererreact-test-rendererpackage.json@testing-library/react-nativetest-rendererreact-test-renderergetByRolegetByLabelTextgetByPlaceholderTextgetByTextgetByDisplayValuegetByTestIdgetByRolegetByLabelTextgetByPlaceholderTextgetByTextgetByDisplayValuegetByTestId| Variant | Use case | Returns | Async |
|---|---|---|---|
| Element must exist | element instance (throws) | No |
| Multiple must exist | element instance[] (throws) | No |
| Check non-existence ONLY | element instance | null | No |
| Count elements | element instance[] | No |
| Wait for element | | Yes |
| Wait for multiple | | Yes |
| 变体 | 使用场景 | 返回值 | 是否异步 |
|---|---|---|---|
| 元素必须存在 | 元素实例(不存在则抛出错误) | 否 |
| 多个元素必须存在 | 元素实例数组(不存在则抛出错误) | 否 |
| 仅用于检查元素不存在 | 元素实例 | null | 否 |
| 统计元素数量 | 元素实例数组 | 否 |
| 等待元素出现 | | 是 |
| 等待多个元素出现 | | 是 |
userEventfireEventconst 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 }); // scrollfireEventuserEventfireEvent.press(element);
fireEvent.changeText(textInput, 'new text');
fireEvent(element, 'blur');userEventfireEventconst user = userEvent.setup();
await user.press(element); // 完整的点击序列
await user.longPress(element, { duration: 800 }); // 长按
await user.type(textInput, 'Hello'); // 逐字符输入
await user.clear(textInput); // 清空TextInput
await user.paste(textInput, 'pasted text'); // 粘贴到TextInput
await user.scrollTo(scrollView, { y: 100 }); // 滚动fireEventuserEventfireEvent.press(element);
fireEvent.changeText(textInput, 'new text');
fireEvent(element, 'blur');@testing-library/react-native| Matcher | Use for |
|---|---|
| Element exists in tree |
| Element visible (not hidden/display:none) |
| Disabled state via |
| Checked state |
| Selected state |
| Expanded state |
| Busy state |
| Text content match |
| TextInput display value |
| Accessible name |
| Accessibility value |
| Style match |
| Prop check (last resort) |
| Contains child element |
| No children |
@testing-library/react-native| 匹配器 | 适用场景 |
|---|---|
| 元素存在于组件树中 |
| 元素可见(未被隐藏/未设置display:none) |
| 通过 |
| 选中状态 |
| 选中状态(如选项卡) |
| 展开/折叠状态 |
| 忙碌状态 |
| 文本内容匹配 |
| TextInput显示值 |
| 可访问名称 |
| 可访问值 |
| 样式匹配 |
| 属性检查(最后选择的方案) |
| 包含子元素 |
| 无子元素 |
screenrender()getByRole{ name: '...' }queryBy*.not.toBeOnTheScreen()findBy*waitForgetBy*waitForfireEventuserEventwaitForwaitForact()renderfireEventuserEventcleanup()rolearia-labelaria-disabledaccessibility*screenrender()getByRole{ name: '...' }queryBy*.not.toBeOnTheScreen()findBy*waitForgetBy*waitForfireEventuserEventwaitForwaitForact()renderfireEventuserEventcleanup()rolearia-labelaria-disabledaccessibility**ByRole*ByRolebuttontextheadingheadersearchboxswitchcheckboxradioimglinkalertmenumenuitemtabtablistprogressbarsliderspinbuttontimertoolbargetByRole{ name, disabled, selected, checked, busy, expanded, value: { min, max, now, text } }*ByRoleTextTextInputSwitchViewaccessible={true}PressableTouchableOpacitybuttontextheadingheadersearchboxswitchcheckboxradioimglinkalertmenumenuitemtabtablistprogressbarsliderspinbuttontimertoolbargetByRole{ name, disabled, selected, checked, busy, expanded, value: { min, max, now, text } }*ByRoleTextTextInputSwitchViewaccessible={true}PressableTouchableOpacity// 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 })// 正确做法:先执行操作,再等待结果
fireEvent.press(button);
await waitFor(() => {
expect(screen.getByText('Result')).toBeOnTheScreen();
});
// 更优做法:使用findBy*替代
fireEvent.press(button);
expect(await screen.findByText('Result')).toBeOnTheScreen();waitFor(cb, { timeout: 1000, interval: 50 })userEventjest.useFakeTimers();
test('with fake timers', async () => {
const user = userEvent.setup();
render(<Component />);
await user.press(screen.getByRole('button'));
// ...
});userEventjest.useFakeTimers();
test('with fake timers', async () => {
const user = userEvent.setup();
render(<Component />);
await user.press(screen.getByRole('button'));
// ...
});wrapperfunction renderWithProviders(ui: React.ReactElement) {
return render(ui, {
wrapper: ({ children }) => (
<ThemeProvider>
<AuthProvider>{children}</AuthProvider>
</ThemeProvider>
),
});
}wrapperfunction renderWithProviders(ui: React.ReactElement) {
return render(ui, {
wrapper: ({ children }) => (
<ThemeProvider>
<AuthProvider>{children}</AuthProvider>
</ThemeProvider>
),
});
}