Simple and complete React Native testing utilities that encourage good testing practices
npx @tessl/cli install tessl/npm-testing-library--react-native@13.3.0React Native Testing Library provides simple and complete testing utilities that encourage good testing practices for React Native applications. Built on react-test-renderer, it focuses on testing components the way users interact with them rather than implementation details, promoting maintainable tests that give confidence in application behavior.
npm install --save-dev @testing-library/react-nativeimport { render, screen, fireEvent, waitFor, userEvent } from "@testing-library/react-native";For pure mode (manual cleanup):
import { render, screen, fireEvent, waitFor, userEvent } from "@testing-library/react-native/pure";For Jest matchers only:
import "@testing-library/react-native/matchers";import React from "react";
import { Text, View, Pressable } from "react-native";
import { render, screen, fireEvent } from "@testing-library/react-native";
function Button({ onPress, children }) {
return (
<Pressable onPress={onPress} testID="button">
<Text>{children}</Text>
</Pressable>
);
}
test("calls onPress when pressed", () => {
const handlePress = jest.fn();
render(<Button onPress={handlePress}>Press me</Button>);
// Find element by text or testID
const button = screen.getByText("Press me");
// or: const button = screen.getByTestId("button");
// Interact with element
fireEvent.press(button);
// Assert behavior
expect(handlePress).toHaveBeenCalledTimes(1);
});React Native Testing Library consists of several key systems:
Core rendering functionality for React Native components with deep rendering and lifecycle management.
function render<T>(
component: React.ReactElement<T>,
options?: RenderOptions
): RenderResult;
interface RenderOptions {
wrapper?: React.ComponentType<any>;
concurrentRoot?: boolean;
createNodeMock?: (element: React.ReactElement) => unknown;
unstable_validateStringsRenderedWithinText?: boolean;
}
interface RenderResult {
// DOM access
root: ReactTestInstance;
UNSAFE_root: ReactTestInstance;
// Utilities
debug: DebugFunction;
rerender: (element: React.ReactElement) => void;
unmount: () => void;
toJSON: () => ReactTestRendererJSON | null;
// All query methods (getBy*, getAllBy*, queryBy*, queryAllBy*, findBy*, findAllBy*)
// ... (queries omitted for brevity in overview)
}Comprehensive system for finding elements using various strategies including text content, accessibility properties, test IDs, and roles.
// Text queries
function getByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance;
function getAllByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance[];
function queryByText(text: string | RegExp, options?: TextMatchOptions): ReactTestInstance | null;
function findByText(text: string | RegExp, options?: TextMatchOptions & WaitForOptions): Promise<ReactTestInstance>;
// TestID queries
function getByTestId(testId: string | RegExp, options?: TestIdOptions): ReactTestInstance;
function getAllByTestId(testId: string | RegExp, options?: TestIdOptions): ReactTestInstance[];
// Role queries
function getByRole(role: string, options?: RoleOptions): ReactTestInstance;
function getAllByRole(role: string, options?: RoleOptions): ReactTestInstance[];
// Accessibility queries
function getByLabelText(text: string | RegExp, options?: LabelTextOptions): ReactTestInstance;
function getByHintText(text: string | RegExp, options?: HintTextOptions): ReactTestInstance;Realistic user interaction simulation supporting press events, text input, scrolling, and other React Native-specific gestures.
// FireEvent - synchronous events
declare const fireEvent: {
press(element: ReactTestInstance): void;
changeText(element: ReactTestInstance, text: string): void;
scroll(element: ReactTestInstance, eventData?: object): void;
// ... additional event types
};
// UserEvent - more realistic interactions
declare const userEvent: {
setup(config?: UserEventConfig): UserEventInstance;
press(element: ReactTestInstance): Promise<void>;
longPress(element: ReactTestInstance, options?: PressOptions): Promise<void>;
type(element: ReactTestInstance, text: string, options?: TypeOptions): Promise<void>;
clear(element: ReactTestInstance): Promise<void>;
paste(element: ReactTestInstance, text: string): Promise<void>;
scrollTo(element: ReactTestInstance, options: ScrollToOptions): Promise<void>;
};Built-in utilities for handling asynchronous behavior, waiting for conditions, and testing time-dependent components.
function waitFor<T>(
expectation: () => T,
options?: WaitForOptions
): Promise<T>;
function waitForElementToBeRemoved<T>(
callback: (() => T) | T,
options?: WaitForOptions
): Promise<void>;
interface WaitForOptions {
timeout?: number;
interval?: number;
onTimeout?: (error: Error) => Error;
}Extended Jest matchers specifically designed for React Native component testing and assertions.
// Visibility and state matchers
expect(element).toBeBusy();
expect(element).toBeChecked();
expect(element).toBeDisabled();
expect(element).toBeEnabled();
expect(element).toBeVisible();
expect(element).toBeOnTheScreen();
// Content matchers
expect(element).toHaveTextContent(text: string | RegExp);
expect(element).toHaveDisplayValue(value: string | RegExp);
expect(element).toHaveAccessibleName(name: string | RegExp);
// Property matchers
expect(element).toHaveProp(prop: string, value?: any);
expect(element).toHaveStyle(style: object);
expect(element).toContainElement(element: ReactTestInstance);Specialized utilities for testing React hooks in isolation with proper act wrapping and lifecycle management.
function renderHook<Result, Props>(
hook: (props: Props) => Result,
options?: RenderHookOptions<Props>
): RenderHookResult<Result, Props>;
interface RenderHookOptions<Props> {
initialProps?: Props;
wrapper?: React.ComponentType<any>;
concurrentRoot?: boolean;
}
interface RenderHookResult<Result, Props> {
result: { current: Result };
rerender: (props?: Props) => void;
unmount: () => void;
}Global configuration options and setup utilities for customizing library behavior across your test suite.
function configure(options: Partial<Config>): void;
function resetToDefaults(): void;
interface Config {
asyncUtilTimeout: number;
defaultIncludeHiddenElements: boolean;
defaultDebugOptions?: Partial<DebugOptions>;
concurrentRoot: boolean;
}// React Test Renderer types
type ReactTestInstance = {
type: string | React.ComponentType;
props: { [propName: string]: any };
parent: ReactTestInstance | null;
children: Array<ReactTestInstance | string>;
// ... additional properties
};
// Common option types
interface TextMatchOptions {
exact?: boolean;
normalizer?: NormalizerFn;
includeHiddenElements?: boolean;
}
interface WaitForOptions {
timeout?: number;
interval?: number;
onTimeout?: (error: Error) => Error;
}
// Utility types
type RefObject<T> = { current: T };
interface Point { x: number; y: number; }
interface Size { width: number; height: number; }