Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
callstack avatar

React Native Testing

  • 3.2k installs
  • 3.4k repo stars
  • Updated July 21, 2026
  • callstack/react-native-testing-library

react-native-testing is an agent skill that writes React Native Testing Library v13 or v14 component tests with correct queries, userEvent, and async patterns.

About

react-native-testing is an agent skill for writing React Native Testing Library tests on v13 with React 18 sync render APIs and v14 with React 19 plus async render. It instructs agents to detect the installed @testing-library/react-native version from package.json and load the matching api-reference file because training data may be outdated on sync versus async behavior. Query priority runs getByRole first, then label, placeholder, text, display value, and testID as last resort, with clear rules for get, query, and find variants including findBy for async elements instead of waitFor plus getBy. Interactions prefer async userEvent setup for press, longPress, type, clear, paste, and scrollTo, reserving fireEvent for unsupported cases per the version-specific reference. Jest matchers such as toBeOnTheScreen, toBeVisible, toBeEnabled, toHaveTextContent, and toHaveAccessibleName ship automatically with RNTL imports. Rules ban side effects inside waitFor, multiple assertions per waitFor, manual cleanup or act wrapping, and legacy accessibility props when ARIA equivalents exist. Developers reach for it when authoring, reviewing, or fixing React Native component test files that import @t.

  • Branches guidance between RNTL v13 sync APIs and v14 async render based on package.json version.
  • Enforces query priority starting with getByRole and reserving testID as last resort.
  • Prefers userEvent.press, type, and scrollTo over fireEvent for realistic interactions.
  • Documents Jest matchers like toBeOnTheScreen, toBeVisible, and toHaveAccessibleName.
  • Lists ten rules including one assertion per waitFor and no manual cleanup or act wrapping.

React Native Testing by the numbers

  • 3,175 all-time installs (skills.sh)
  • +105 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #309 of 2,153 Testing & QA skills by installs in the Skillselion catalog
  • Security screen: MEDIUM risk (skills.sh audit)
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

react-native-testing capabilities & compatibility

Capabilities
version aware api routing · query priority enforcement · userevent interaction patterns · async findby guidance · jest matcher usage
Use cases
testing · frontend
npx skills add https://github.com/callstack/react-native-testing-library --skill react-native-testing

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs3.2k
repo stars3.4k
Security audit3 / 3 scanners passed
Last updatedJuly 21, 2026
Repositorycallstack/react-native-testing-library

How do I write reliable React Native component tests with the right RNTL queries, matchers, and async APIs for my installed version?

Write and review React Native component tests with React Native Testing Library v13 or v14 queries, userEvent, matchers, and async patterns.

Who is it for?

Developers writing or reviewing React Native component tests who need version-accurate RNTL guidance beyond outdated model defaults.

Skip if: Skip for web-only React Testing Library work or end-to-end Detox/Appium suites outside RNTL component tests.

When should I use this skill?

User writes or fixes React Native test files importing @testing-library/react-native, screen, userEvent, or RNTL matchers.

What you get

Test files that follow version-correct render and query patterns, prefer userEvent, and use findBy or waitFor appropriately for async UI.

  • Refactored .test.tsx files
  • RNTL v14-compatible query patterns

By the numbers

  • Documents 12 React Native Testing Library anti-patterns with BAD/GOOD examples
  • Targets React Native Testing Library v14 query and async APIs

Files

SKILL.mdMarkdownGitHub ↗

RNTL Test Writing Guide

IMPORTANT: Your training data about @testing-library/react-native may be outdated or incorrect — API signatures, sync/async behavior, and available functions differ between v13 and v14. Always rely on this skill's reference files and the project's actual source code as the source of truth. Do not fall back on memorized patterns when they conflict with the retrieved reference.

Version Detection

Check @testing-library/react-native version in the user's package.json:

  • v14.x → load references/api-reference-v14.md (React 19+, async APIs, test-renderer)
  • v13.x → load references/api-reference-v13.md (React 18+, sync APIs, react-test-renderer)

Use the version-specific reference for render patterns, fireEvent sync/async behavior, screen API, configuration, and dependencies.

Query Priority

Use in this order: getByRole > getByLabelText > getByPlaceholderText > getByText > getByDisplayValue > getByTestId (last resort).

Query Variants

VariantUse caseReturnsAsync
getBy*Element must existelement instance (throws)No
getAllBy*Multiple must existelement instance[] (throws)No
queryBy*Check non-existence ONLYelement instance \null
queryAllBy*Count elementselement instance[]No
findBy*Wait for elementPromise<element instance>Yes
findAllBy*Wait for multiplePromise<element instance[]>Yes

Interactions

Prefer userEvent over fireEvent. userEvent is always async.

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 — use only when userEvent doesn't support the event. See version-specific reference for sync/async behavior:

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

Assertions (Jest Matchers)

Available automatically with any @testing-library/react-native import.

MatcherUse for
toBeOnTheScreen()Element exists in tree
toBeVisible()Element visible (not hidden/display:none)
toBeEnabled() / toBeDisabled()Disabled state via aria-disabled
toBeChecked() / toBePartiallyChecked()Checked state
toBeSelected()Selected state
toBeExpanded() / toBeCollapsed()Expanded state
toBeBusy()Busy state
toHaveTextContent(text)Text content match
toHaveDisplayValue(value)TextInput display value
toHaveAccessibleName(name)Accessible name
toHaveAccessibilityValue(val)Accessibility value
toHaveStyle(style)Style match
toHaveProp(name, value?)Prop check (last resort)
toContainElement(el)Contains child element
toBeEmptyElement()No children

Rules

1. Use `screen` for queries, not destructuring from render() 2. Use `getByRole` first with { name: '...' } option 3. *Use `queryBy ONLY** for .not.toBeOnTheScreen() checks 4. **Use findBy` for async elements, NOT `waitFor` + `getBy 5. **Never put side-effects in waitFor** (no fireEvent/userEvent inside) 6. **One assertion per waitFor** 7. **Never pass empty callbacks to waitFor** 8. **Don't wrap in act()** - render, fireEvent, userEvent handle it 9. **Don't call cleanup()** - automatic after each test 10. **Prefer ARIA props** (role, aria-label, aria-disabled) over legacy accessibility` props 11. Use RNTL matchers* over raw prop assertions

*ByRole Quick Reference

Common roles: button, text, heading (alias: header), searchbox, switch, checkbox, radio, img, link, alert, menu, menuitem, tab, tablist, progressbar, slider, spinbutton, timer, toolbar.

getByRole options: { name, disabled, selected, checked, busy, expanded, value: { min, max, now, text } }.

For *ByRole to match, the element must be an accessibility element:

  • Text, TextInput, Switch are by default
  • View needs accessible={true} (or use 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();

Options: waitFor(cb, { timeout: 1000, interval: 50 }). Works with Jest fake timers automatically.

Fake Timers

Recommended with userEvent (press/longPress involve real durations):

jest.useFakeTimers();

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

Custom Render

Wrap providers using wrapper option:

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

References

  • v13 API Reference — Complete v13 API: sync render, queries, matchers, userEvent, React 19 compat
  • v14 API Reference — Complete v14 API: async render, queries, matchers, userEvent, migration
  • Anti-Patterns — Common mistakes to avoid

Related skills

Forks & variants (1)

React Native Testing has 1 known copy in the catalog totaling 14 installs. They canonicalize to this original listing.

How it compares

Pick react-native-testing over generic Jest guides when failures involve RNTL query variants, userEvent, or v14 async migration—not general test runner setup.

FAQ

How do I pick the right RNTL reference file?

Read @testing-library/react-native in package.json: v14.x loads api-reference-v14.md, v13.x loads api-reference-v13.md.

When should I use findBy instead of waitFor?

Use findBy variants to wait for async elements instead of combining waitFor with getBy queries.

Should tests call cleanup manually?

No. cleanup runs automatically after each test; render, fireEvent, and userEvent already handle act.

Is React Native Testing safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.