Going Pro: Job-Ready React NativePro· 45 min read

Testing with Jest & React Native Testing Library

Job-ready apps have tests — Jest checks plain functions, and React Native Testing Library checks that components render and respond to taps.

What you will learn

  • Explain why automated tests matter
  • Write a unit test with Jest
  • Test a component’s render and a button press with RNTL

Why test at all

A test is code that checks your other code does the right thing — automatically. Instead of tapping through the app by hand after every change, you run the tests and they tell you in seconds if anything broke. Serious bootcamps and job descriptions expect this, because tests catch regressions (old features breaking when you add new ones) before users do.

Two tools cover most React Native testing:

  • Jest — the test runner and assertion library. It finds your test files, runs them, and lets you state what you expect (e.g. "this should equal 4").
  • React Native Testing Library (RNTL) — renders a component in a test environment so you can check what is on screen and simulate taps, the way a user would.

New Expo apps come with the jest-expo preset configured. Add the testing library (one-time):

Install React Native Testing Library (dev dependency)
npx expo install --dev @testing-library/react-native

Note: Output: (Adds the library for development only. Tests are not shipped in your app.)

A unit test with Jest

Start with the simplest case: a plain function. A unit test checks one small piece in isolation. Jest’s test describes a case, and expect(...).toBe(...) states what should be true. Say we have a helper that adds tax:

A Jest unit test for a plain function
// total.js
export function withTax(price) {
  return price * 1.18;   // add 18% tax
}

// total.test.js
import { withTax } from './total';

test('adds 18% tax to a price', () => {
  expect(withTax(100)).toBe(118);
});

Note: Output (in the terminal, after running npm test): PASS total.test.js ✓ adds 18% tax to a price Jest ran the function with 100, compared the result to 118, and they matched — so the test passes. If someone later broke withTax, this test would fail and tell you.

Testing a component with RNTL

Components need more than a value check — you want to know they render the right text and respond to taps. RNTL’s render draws the component in memory, screen.getByText finds text on it, and fireEvent.press simulates a tap. Here we test a counter:

RNTL renders the component, finds text, and simulates a press
import { render, screen, fireEvent } from '@testing-library/react-native';
import { useState } from 'react';
import { Text, Button, View } from 'react-native';

function Counter() {
  const [n, setN] = useState(0);
  return (
    <View>
      <Text>Count: {n}</Text>
      <Button title="Add" onPress={() => setN(n + 1)} />
    </View>
  );
}

test('increments the count when Add is pressed', () => {
  render(<Counter />);
  expect(screen.getByText('Count: 0')).toBeTruthy();   // starts at 0
  fireEvent.press(screen.getByText('Add'));            // tap the button
  expect(screen.getByText('Count: 1')).toBeTruthy();   // now 1
});

Note: Output: PASS ✓ increments the count when Add is pressed The test rendered Counter, confirmed it showed "Count: 0", simulated tapping "Add", then confirmed it showed "Count: 1" — exactly what a user would experience, but checked automatically.

How a test run works, step by step

When you run npm test, here is what happens, in order:

  1. Jest finds every file ending in .test.js (or .test.tsx) in your project.
  2. It runs each test(...) block one by one.
  3. For component tests, RNTL render draws the component in a fake screen held in memory (no real phone needed).
  4. Your expect(...) lines and fireEvent calls check the output and simulate user actions.
  5. Each assertion either passes (✓) or fails (✗) with a message showing what was expected versus what it got.
  6. Jest prints a summary — how many passed and failed — and returns success only if every test passed, which is what a CI pipeline checks before allowing a merge.

Tip: Aim tests at behaviour users care about — "does the right text show", "does the button do the thing" — using getByText and getByRole, rather than testing internal details. Tests written from the user’s point of view break less often when you refactor.

Watch out: Do not chase 100% coverage of every line, especially as a beginner. A handful of meaningful tests on your important logic and key screens is far more valuable than many brittle tests of trivial code.

Q. What does React Native Testing Library add on top of Jest?

Answer: Jest runs tests and checks values; RNTL renders a component in a test environment so you can assert on what is on screen and fire events like presses, the way a user would.

✍️ Practice

  1. Write a Jest test for a discount(price) function that takes 10% off and check discount(200) is 180.
  2. Use RNTL to test a component that shows a greeting and check the greeting text is present.

🏠 Homework

  1. Add one unit test and one component test to an earlier lesson’s code (e.g. the counter), and run npm test until both pass.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →