| name | rn-testing |
| description | Test strategy and setup for Expo React Native apps. Jest + React Native Testing Library for unit/component tests, Maestro for end-to-end. Apply when writing tests, configuring CI test runs, or mocking native modules. |
| metadata | {"owner":"rn-builder","status":"stable"} |
rn-testing
Purpose
Single source of truth for testing an Expo React Native app, from a unit test on a Zod schema all the way through a Maestro flow that signs in and submits a form on a real iOS simulator.
When to Apply
Use this skill when the task is:
- Writing a new test (unit, hook, component, or E2E)
- Setting up Jest + RNTL in a fresh project
- Setting up Maestro for E2E coverage
- Mocking a native module (
expo-secure-store, react-native-mmkv, etc.) in tests
- Wiring tests into CI (GitHub Actions, EAS, or otherwise)
- Diagnosing test flake
Do not use this skill when:
- The task is "the app is slow" → that's perf, read the Callstack skill.
- The task is "EAS build is failing" → that's release, read
../rn-release-eas/SKILL.md.
Testing Pyramid for RN
| Layer | Tool | What it covers | Run cost |
|---|
| Unit | Jest | Pure functions, Zod schemas, Zustand stores, utility hooks | Cheapest, run on every commit |
| Component | Jest + React Native Testing Library | Single components in isolation, rendering + interactions | Cheap, run on every commit |
| Integration | Jest + RNTL with QueryClient + providers | Whole screen rendering, mocked API | Moderate, run pre-merge |
| E2E | Maestro | Full flows on a real simulator/emulator | Expensive, run on PR + nightly |
Bias toward unit and component. E2E is for golden paths, not exhaustive coverage.
Problem → Reference
Default Choices
| Concern | Default | Notes |
|---|
| Unit / component runner | Jest with jest-expo preset | Comes with the Expo template |
| Component testing | React Native Testing Library | Always queries by accessibility, not implementation |
| E2E | Maestro | Preferred over Detox for new projects — YAML flows, no native build step |
| Snapshot testing | Avoid by default | Only for genuinely stable serializable output (e.g., Zod schema → JSON) |
| Coverage threshold | 60% lines on src/, 80% on src/features/*/api.ts and src/utils/* | Pragmatic, not arbitrary |
| Visual regression | Not part of default stack | Add only when designers ask for it |
What NOT to Test
- React Navigation / Expo Router itself — it's library code.
- Third-party SDKs — Sentry, Clerk, Supabase. Trust them.
- Layout pixel-perfection — that's what design review is for, not Jest snapshots.
- Reanimated worklets via Jest — worklets need the UI thread runtime; mock them or test the surrounding logic.
What MUST Be Tested
- Zod schemas — parsing real-world fixture payloads, including known-bad ones.
- Pure utility functions — formatters, parsers, validators in
src/utils/.
- Zustand stores — state transitions, persistence, selectors.
- API hooks — query keys, mutation invalidations, error handling (via MSW or mocked apiClient).
- Critical user flows — sign-in, checkout, primary CTA → E2E.
Verification
After scaffolding or modifying the test setup:
npx jest --listTests shows expected test files.
npx jest passes locally.
maestro test e2e/ passes on at least one simulator.
- CI runs both within reasonable wall-clock time (< 10 min for Jest, < 20 min for Maestro per platform).