Paramclasses Academy - Blog

Tutorials Details

←
Post 33 of 39
→

React Native App Testing: Tools and Best Practices

React Native App Testing: Tools and Best Practices

November 5, 2026

1. Introduction

Testing is an important part of mobile app development. It helps developers find bugs, verify application behavior, and maintain app quality before releasing an application.

In React Native, we can test JavaScript logic, UI components, user interactions, and complete application workflows using different testing tools.

In this tutorial, we will learn how to test a React Native application using Jest and React Native Testing Library.

What You Will Learn

  • What is software testing?

  • Why is testing important in React Native?

  • Types of mobile application testing

  • Introduction to Jest

  • Introduction to React Native Testing Library

  • Setting up Jest in an Expo project

  • Writing unit tests

  • Testing React Native components

  • Testing buttons and user interactions

  • Testing application logic

  • Understanding test results

  • Testing best practices

2. What Is App Testing?

App testing is the process of checking whether an application works according to its requirements.

For example, imagine that you have created a student management application.

You should test whether:

  • The application displays the student list correctly.

  • The Add Student button works.

  • Empty student names are rejected.

  • Student information is saved correctly.

  • The application displays the correct message.

Testing helps identify problems before users experience them.

3. Types of Testing in React Native

3.1 Unit Testing

Unit testing checks individual functions or small pieces of application logic.

Example:

function calculateTotal(price, quantity) {
  return price * quantity;
}

expect(calculateTotal(100, 2)).toBe(200);

3.2 Component Testing

Component testing checks whether individual UI components render and behave correctly.

Example:

  • Does a button appear?

  • Does a heading display the correct text?

  • Does a component respond to user interaction?

3.3 Integration Testing

Integration testing checks whether multiple parts of an application work together.

For example, checking whether a form correctly communicates with an application data layer.

3.4 End-to-End Testing

End-to-end testing checks complete user workflows in a running application.

For example:

  1. Open the application.

  2. Navigate to the registration screen.

  3. Enter user details.

  4. Press Register.

  5. Verify the success screen.

Tools such as Maestro and Detox can help automate these workflows.

4. Testing Tools for React Native

Jest

Jest is a JavaScript testing framework. It helps developers write and execute tests, check expected results, and generate test coverage reports.

React Native Testing Library

React Native Testing Library helps test React Native components by rendering them and interacting with them in a simulated testing environment.

It encourages tests based on how users interact with an application.

Maestro

Maestro is an end-to-end testing tool that allows developers to automate mobile application workflows.

Detox

Detox is an end-to-end testing framework designed for React Native applications.

In this tutorial, we will primarily use Jest and React Native Testing Library.

5. Create a React Native Testing Project

First, create a new Expo project.

Open your terminal and execute:

npx create-expo-app@latest StudentTestingApp --template blank

Open the project:

cd StudentTestingApp

Start the application:

npx expo start

You can run the application using Expo Go or an appropriate development build.

6. Install Testing Dependencies

Install Jest and the Expo Jest preset:

npx expo install jest-expo jest @types/jest --dev

Install React Native Testing Library:

npx expo install @testing-library/react-native --dev

These packages provide the tools required for writing and executing component tests.

Note: Follow the current Expo installation guide when upgrading dependencies. Use compatible package versions for your Expo SDK.

7. Configure Jest

Open your package.json file.

Add the following configuration:

{
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "test": "jest"
  },
  "jest": {
    "preset": "jest-expo"
  }
}

Keep your existing dependencies and other scripts. Add or merge the testing configuration instead of replacing the entire file.

Now Jest is configured for the Expo project.

8. Create a Simple Testing Project Structure

Organize your application files like this:

StudentTestingApp/
│
├── App.js
│
├── src/
│   ├── components/
│   │   └── StudentForm.js
│   │
│   └── utils/
│       └── studentUtils.js
│
└── __tests__/
    ├── studentUtils.test.js
    └── StudentForm.test.js

This structure separates application components, utility functions, and test files.

9. Create a Utility Function

Create the following file:

src/utils/studentUtils.js

Add this code:

export function validateStudentName(name) {
  return name.trim().length >= 3;
}

export function createStudent(name) {
  return {
    id: 'student-1',
    name: name.trim(),
    status: 'Active',
  };
}

This file contains two functions.

  • validateStudentName() checks whether the student name contains at least three characters.

  • createStudent() creates a student object.

10. Write Your First Unit Test

Open:

__tests__/studentUtils.test.js

Add this code:

import {
  validateStudentName,
  createStudent,
} from '../src/utils/studentUtils';

describe('Student Utility Tests', () => {

  test('valid student name should return true', () => {
    expect(validateStudentName('Rahul')).toBe(true);
  });

  test('short student name should return false', () => {
    expect(validateStudentName('AB')).toBe(false);
  });

  test('empty student name should return false', () => {
    expect(validateStudentName('')).toBe(false);
  });

  test('student name with spaces should be trimmed', () => {
    expect(validateStudentName(' Rahul ')).toBe(true);
  });

  test('createStudent should return student details', () => {
    const student = createStudent('Rahul');

    expect(student).toEqual({
      id: 'student-1',
      name: 'Rahul',
      status: 'Active',
    });
  });

});

Understanding the Test Code

describe(): Groups related test cases.

test(): Defines an individual test.

expect(): Defines the expected result.

toBe(): Checks a simple value.

toEqual(): Checks object or array values.

Each test checks one specific behavior.

11. Create a Student Form Component

Create:

src/components/StudentForm.js

Add the following code:

import React, { useState } from 'react';

import {
  View,
  Text,
  TextInput,
  Button,
  StyleSheet,
} from 'react-native';

import { validateStudentName } from '../utils/studentUtils';

export default function StudentForm({ onAddStudent }) {

  const [name, setName] = useState('');
  const [message, setMessage] = useState('');

  const handleAddStudent = () => {

    if (!validateStudentName(name)) {
      setMessage('Enter at least 3 characters');
      return;
    }

    onAddStudent(name.trim());

    setName('');
    setMessage('Student added successfully!');
  };

  return (
    <View style={styles.container}>

      <Text style={styles.title}>
        Add New Student
      </Text>

      <TextInput
        style={styles.input}
        placeholder="Enter student name"
        value={name}
        onChangeText={setName}
        accessibilityLabel="Student name"
      />

      <Button
        title="Add Student"
        onPress={handleAddStudent}
      />

      {message !== '' && (
        <Text accessibilityRole="alert" style={styles.message}>
          {message}
        </Text>
      )}

    </View>
  );
}

const styles = StyleSheet.create({

  container: {
    padding: 20,
    backgroundColor: '#FFFFFF',
  },

  title: {
    fontSize: 22,
    fontWeight: 'bold',
    marginBottom: 15,
  },

  input: {
    borderWidth: 1,
    borderColor: '#999999',
    padding: 12,
    marginBottom: 15,
    borderRadius: 8,
  },

  message: {
    marginTop: 12,
    fontSize: 14,
  },

});

This component contains a student input field, an Add Student button, and a message area.

12. Write Component Tests

Create:

__tests__/StudentForm.test.js

Add this code:

import React from 'react';

import {
  render,
  screen,
  fireEvent,
} from '@testing-library/react-native';

import StudentForm from '../src/components/StudentForm';

describe('Student Form Component Tests', () => {

  test('should display student form heading', () => {

    render(
      <StudentForm onAddStudent={jest.fn()} />
    );

    expect(
      screen.getByText('Add New Student')
    ).toBeTruthy();

  });

  test('should display input and button', () => {

    render(
      <StudentForm onAddStudent={jest.fn()} />
    );

    expect(
      screen.getByLabelText('Student name')
    ).toBeTruthy();

    expect(
      screen.getByRole('button', {
        name: 'Add Student',
      })
    ).toBeTruthy();

  });

  test('should show validation error for short name', () => {

    render(
      <StudentForm onAddStudent={jest.fn()} />
    );

    fireEvent.changeText(
      screen.getByLabelText('Student name'),
      'AB'
    );

    fireEvent.press(
      screen.getByRole('button', {
        name: 'Add Student',
      })
    );

    expect(
      screen.getByText('Enter at least 3 characters')
    ).toBeTruthy();

  });

  test('should call onAddStudent with valid name', () => {

    const onAddStudent = jest.fn();

    render(
      <StudentForm onAddStudent={onAddStudent} />
    );

    fireEvent.changeText(
      screen.getByLabelText('Student name'),
      'Rahul'
    );

    fireEvent.press(
      screen.getByRole('button', {
        name: 'Add Student',
      })
    );

    expect(onAddStudent).toHaveBeenCalledWith('Rahul');

    expect(
      screen.getByText('Student added successfully!')
    ).toBeTruthy();

  });

});

What Are We Testing?

  1. The heading appears correctly.

  2. The input field and button are available.

  3. Invalid student names display an error.

  4. Valid student names trigger the expected callback.

  5. A success message appears after adding a student.

The tests focus on visible behavior rather than internal component implementation.

13. Run Your Tests

Open the terminal in your project directory.

Execute:

npm test

Jest will discover and execute your test files.

To run tests once without watch mode:

npx jest --runInBand

To run tests with coverage:

npx jest --coverage

To run a particular test file:

npx jest studentUtils.test.js

14. Understand Test Results

A successful test run may display output similar to this:

PASS  __tests__/studentUtils.test.js
PASS  __tests__/StudentForm.test.js

Test Suites: 2 passed, 2 total
Tests:       9 passed, 9 total
Snapshots:   0 total

This means:

  • PASS: The test file passed.

  • Test Suites: Number of test files executed.

  • Tests: Number of individual test cases.

  • Snapshots: Number of snapshot comparisons.

If a test fails, Jest displays an error message showing the expected and received values.

Read the failure message and correct the application or test code.

15. What Is Snapshot Testing?

Snapshot testing stores a representation of a rendered component and compares future output against that saved snapshot.

It can help detect unexpected UI structure changes.

However, snapshots should be used carefully. A passing snapshot does not prove that the application is usable or that every interaction works correctly.

Prefer meaningful behavior tests for important application features.

16. Testing Best Practices

Follow these practices when testing React Native applications:

  1. Write small tests that check one behavior at a time.

  2. Use meaningful test descriptions.

  3. Test both valid and invalid inputs.

  4. Test user interactions such as button presses.

  5. Prefer accessibility labels and user-facing queries.

  6. Avoid depending heavily on internal component state.

  7. Mock network requests and external services when necessary.

  8. Test important error and loading states.

  9. Keep test files organized.

  10. Run tests before releasing application updates.

17. Important Testing Limitations

Jest and React Native Testing Library do not replace testing on actual Android and iOS devices.

They are useful for JavaScript logic and simulated component behavior, but they cannot fully verify native hardware functionality.

For example, test the following separately on a device or suitable end-to-end environment:

  • Camera access

  • GPS functionality

  • Push notifications

  • Native permissions

  • Actual device navigation

  • Performance on different devices

Use a combination of unit, component, integration, and end-to-end testing for better application quality.

18. Final Project Outcome

After completing this tutorial, you will have created a Student Testing App foundation with:

  • Jest testing configuration

  • Utility function tests

  • React Native component tests

  • Input validation tests

  • Button interaction tests

  • Test result verification

You will understand how to identify errors and verify application behavior before releasing a React Native app.

19. Conclusion

Testing is an essential skill for every React Native developer.

Jest helps test JavaScript logic, while React Native Testing Library helps verify components and user interactions.

By writing meaningful tests and following good testing practices, developers can build more reliable, maintainable, and high-quality mobile applications.

Practice Task: Add an email field to the Student Form and write tests for valid email addresses, invalid email addresses, and empty email input.

20. Frequently Asked Questions

Q1. What is Jest in React Native?

Jest is a JavaScript testing framework used to execute tests and verify expected application behavior.

Q2. What is React Native Testing Library?

It is a library used to render and test React Native components and simulate user interactions.

Q3. What is the difference between unit testing and component testing?

Unit testing checks individual functions or logic, while component testing checks UI rendering and user-facing behavior.

Q4. Can we test React Native apps without a physical device?

Yes. Jest and React Native Testing Library can test many JavaScript functions and components without a physical device. Native hardware features still require suitable device testing.

Q5. What is end-to-end testing?

End-to-end testing verifies complete application workflows from the user's perspective.

Q6. Is testing important before publishing an app?

Yes. Testing helps identify bugs, validate important features, and improve application reliability before release.

←
Post 33 of 39
→