Convert Figma logo to code with AI

callstack logoreact-native-testing-library

🦉 Simple and complete React Native testing utilities that encourage good testing practices.

3,069
271
3,069
14

Top Related Projects

A framework for building native applications using React

11,186

Gray box end-to-end testing and automation framework for mobile apps

Lottie wrapper for React Native.

React Native Mapview component for iOS + Android

A complete native navigation solution for React Native

React Native's Animated library reimplemented

Quick Overview

React Native Testing Library is a lightweight solution for testing React Native components. It provides a set of utility functions that encourage better testing practices by working with actual DOM nodes rather than dealing with instances of rendered React components.

Pros

  • Encourages writing tests that closely resemble how users interact with the app
  • Provides a simple and intuitive API for querying and interacting with components
  • Supports both React Native and Expo projects
  • Actively maintained and has good community support

Cons

  • Learning curve for developers used to enzyme or other testing libraries
  • Limited support for certain complex React Native components
  • May require additional setup for certain testing scenarios
  • Performance can be slower compared to shallow rendering techniques

Code Examples

  1. Rendering a component and querying by text:
import { render, screen } from '@testing-library/react-native';

test('renders greeting', () => {
  render(<Greeting name="World" />);
  const greetingElement = screen.getByText('Hello, World!');
  expect(greetingElement).toBeTruthy();
});
  1. Testing user interaction:
import { render, screen, fireEvent } from '@testing-library/react-native';

test('increments counter on button press', () => {
  render(<Counter />);
  const incrementButton = screen.getByText('Increment');
  const counterText = screen.getByTestId('counter-value');
  
  expect(counterText).toHaveTextContent('0');
  fireEvent.press(incrementButton);
  expect(counterText).toHaveTextContent('1');
});
  1. Testing asynchronous behavior:
import { render, screen, waitFor } from '@testing-library/react-native';

test('loads and displays data', async () => {
  render(<DataFetcher />);
  
  expect(screen.getByText('Loading...')).toBeTruthy();
  
  await waitFor(() => {
    expect(screen.getByText('Data loaded!')).toBeTruthy();
  });
});

Getting Started

  1. Install the library:

    npm install --save-dev @testing-library/react-native
    
  2. Write a test file (e.g., App.test.js):

    import React from 'react';
    import { render, screen } from '@testing-library/react-native';
    import App from './App';
    
    test('renders correctly', () => {
      render(<App />);
      expect(screen.getByText('Welcome to React Native!')).toBeTruthy();
    });
    
  3. Run your tests using Jest:

    npx jest
    

Competitor Comparisons

A framework for building native applications using React

Pros of React Native

  • Comprehensive framework for building cross-platform mobile apps
  • Large ecosystem and community support
  • Extensive documentation and official resources

Cons of React Native

  • Steeper learning curve for beginners
  • Larger project size and potential performance overhead
  • More complex setup and configuration

Code Comparison

React Native (basic component):

import React from 'react';
import { View, Text } from 'react-native';

const MyComponent = () => (
  <View>
    <Text>Hello, React Native!</Text>
  </View>
);

React Native Testing Library (test example):

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

test('renders correctly', () => {
  render(<MyComponent />);
  expect(screen.getByText('Hello, React Native!')).toBeTruthy();
});

Key Differences

  • React Native is a full-fledged framework, while React Native Testing Library is a testing utility
  • React Native focuses on app development, whereas React Native Testing Library specializes in testing React Native components
  • React Native has a broader scope and functionality, while React Native Testing Library is more focused and lightweight

Use Cases

  • Use React Native for building cross-platform mobile applications
  • Use React Native Testing Library for writing and running tests for React Native components and applications
11,186

Gray box end-to-end testing and automation framework for mobile apps

Pros of Detox

  • End-to-end testing framework, allowing for more comprehensive app testing
  • Supports both iOS and Android platforms natively
  • Provides a gray box testing approach, offering more control over the app's internals

Cons of Detox

  • Steeper learning curve due to its comprehensive nature
  • Requires more setup and configuration compared to React Native Testing Library
  • Can be slower to run tests, especially for large test suites

Code Comparison

Detox example:

describe('Login flow', () => {
  it('should login successfully', async () => {
    await element(by.id('email')).typeText('user@example.com');
    await element(by.id('password')).typeText('password123');
    await element(by.text('Login')).tap();
    await expect(element(by.text('Welcome'))).toBeVisible();
  });
});

React Native Testing Library example:

test('login form submits', () => {
  const { getByTestId, getByText } = render(<LoginForm />);
  fireEvent.changeText(getByTestId('email'), 'user@example.com');
  fireEvent.changeText(getByTestId('password'), 'password123');
  fireEvent.press(getByText('Login'));
  expect(getByText('Welcome')).toBeTruthy();
});

Both libraries serve different purposes in the React Native testing ecosystem. Detox focuses on end-to-end testing, while React Native Testing Library is primarily for component and integration testing. The choice between them depends on the specific testing needs of your project.

Lottie wrapper for React Native.

Pros of Lottie React Native

  • Enables the use of complex animations in React Native apps
  • Supports both iOS and Android platforms
  • Provides a simple API for controlling animations

Cons of Lottie React Native

  • Larger bundle size due to animation capabilities
  • May require more system resources for complex animations
  • Limited to animations created with Adobe After Effects

Code Comparison

Lottie React Native:

import LottieView from 'lottie-react-native';

<LottieView
  source={require('./animation.json')}
  autoPlay
  loop
/>

React Native Testing Library:

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

test('button press', () => {
  const { getByText } = render(<MyComponent />);
  fireEvent.press(getByText('Press me'));
});

Summary

Lottie React Native is focused on adding high-quality animations to React Native apps, while React Native Testing Library is designed for testing React Native components. Lottie offers rich animation capabilities but may increase app size and resource usage. React Native Testing Library provides a lightweight testing solution but doesn't add visual enhancements to the app. The choice between these libraries depends on whether the primary need is for animations or testing in a React Native project.

React Native Mapview component for iOS + Android

Pros of react-native-maps

  • Provides a comprehensive mapping solution specifically for React Native applications
  • Offers a wide range of customization options for map markers, polygons, and overlays
  • Supports both iOS and Android platforms with native map implementations

Cons of react-native-maps

  • Larger package size and potential performance impact due to its comprehensive feature set
  • May require additional setup and configuration compared to simpler mapping solutions
  • Limited to mapping functionality, whereas react-native-testing-library is a general-purpose testing tool

Code Comparison

react-native-maps:

import MapView, { Marker } from 'react-native-maps';

<MapView
  initialRegion={{
    latitude: 37.78825,
    longitude: -122.4324,
    latitudeDelta: 0.0922,
    longitudeDelta: 0.0421,
  }}
>
  <Marker coordinate={{ latitude: 37.78825, longitude: -122.4324 }} />
</MapView>

react-native-testing-library:

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

const { getByTestId } = render(<MyComponent />);
const button = getByTestId('my-button');
fireEvent.press(button);

While react-native-maps focuses on providing mapping functionality, react-native-testing-library is designed for testing React Native components. The code examples demonstrate their distinct purposes and usage patterns.

A complete native navigation solution for React Native

Pros of React Native Navigation

  • Provides a native navigation solution with better performance and smoother transitions
  • Offers more advanced navigation features like deep linking and custom transitions
  • Supports both iOS and Android platforms with native implementations

Cons of React Native Navigation

  • Steeper learning curve due to its more complex API and setup process
  • Requires additional native code integration, which can be challenging for some developers
  • May have compatibility issues with certain React Native versions or other libraries

Code Comparison

React Native Navigation:

Navigation.setRoot({
  root: {
    stack: {
      children: [
        { component: { name: 'Home' } }
      ]
    }
  }
});

React Native Testing Library:

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

test('renders correctly', () => {
  const { getByText } = render(<MyComponent />);
  const element = getByText('Hello, World!');
  expect(element).toBeTruthy();
});

Summary

React Native Navigation is a powerful navigation solution for React Native apps, offering native performance and advanced features. However, it comes with a steeper learning curve and more complex setup compared to React Native Testing Library. The latter focuses on testing React Native components and is generally easier to integrate into existing projects. While React Native Navigation handles app navigation, React Native Testing Library provides tools for testing UI components and user interactions.

React Native's Animated library reimplemented

Pros of React Native Reanimated

  • Provides a powerful and flexible animation system for React Native
  • Offers better performance for complex animations by running them on the native thread
  • Supports gesture-based animations and interactions

Cons of React Native Reanimated

  • Steeper learning curve compared to React Native Testing Library
  • Requires additional setup and configuration
  • May introduce complexity for simple animation tasks

Code Comparison

React Native Reanimated:

import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';

const animatedStyles = useAnimatedStyle(() => {
  return { transform: [{ translateX: withSpring(offset.value * 255) }] };
});

React Native Testing Library:

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

test('button press increments counter', () => {
  const { getByText } = render(<Counter />);
  fireEvent.press(getByText('Increment'));
  expect(getByText('Count: 1')).toBeTruthy();
});

While React Native Reanimated focuses on creating smooth and performant animations, React Native Testing Library is designed for testing React Native components. The code examples highlight their different purposes, with Reanimated demonstrating animation creation and Testing Library showing component interaction testing.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

React Native Testing Library

owl

Developer-friendly and complete React Native testing utilities that encourage good testing practices.

Version Build Status Code Coverage Downloads MIT License Sponsored by Callstack

The problem

You want to write maintainable tests for your React Native components. As a part of this goal, you want your tests to avoid including implementation details of your components and rather focus on making your tests give you the confidence for which they are intended. As part of this, you want your tests to be maintainable in the long run so refactors of your components (changes to implementation but not functionality) don't break your tests and slow you and your team down.

This solution

The React Native Testing Library (RNTL) is a comprehensive solution for testing React Native components. It provides React Native runtime simulation on top of react-test-renderer, in a way that encourages better testing practices. Its primary guiding principle is:

The more your tests resemble the way your software is used, the more confidence they can give you.

This project is inspired by React Testing Library. Tested to work with Jest, but it should work with other test runners as well.

Installation

Open a Terminal in your project's folder and run:

# Yarn install:
yarn add --dev @testing-library/react-native

# NPM install
npm install --save-dev @testing-library/react-native

This library has a peerDependencies listing for react-test-renderer. Make sure that your react-test-renderer version matches exactly the react version, avoid using ^ in version number.

Additional Jest matchers

You can use the built-in Jest matchers by adding the following line to your jest-setup.ts file (configured using setupFilesAfterEnv):

import '@testing-library/react-native/extend-expect';

Example

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

// It is recommended to use userEvent with fake timers
// Some events involve duration so your tests may take a long time to run.
jest.useFakeTimers();

test('form submits two answers', async () => {
  const questions = ['q1', 'q2'];
  const onSubmit = jest.fn();

  const user = userEvent.setup();
  render(<QuestionsBoard questions={questions} onSubmit={onSubmit} />);

  const answerInputs = screen.getAllByLabelText('answer input');

  // simulates the user focusing on TextInput and typing text one char at a time
  await user.type(answerInputs[0], 'a1');
  await user.type(answerInputs[1], 'a2');

  // simulates the user pressing on any pressable element
  await user.press(screen.getByRole('button', { name: 'Submit' }));

  expect(onSubmit).toHaveBeenCalledWith({
    1: { q: 'q1', a: 'a1' },
    2: { q: 'q2', a: 'a2' },
  });
});

You can find the source of QuestionsBoard component and this example here.

API / Usage

React Native Testing Library consists of following APIs:

Migration Guides

Troubleshooting

Community Resources

Check out our list of Community Resources about RNTL.

Made with ❤️ at Callstack

React Native Testing Library is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. Callstack is a group of React and React Native geeks, contact us at hello@callstack.com if you need any help with these or just want to say hi!

Like the project? ⚛️ Join the team who does amazing stuff for clients and drives React Native Open Source! 🔥


Supported and used by Rally Health.

NPM DownloadsLast 30 Days