React Testing Library (RTL) — это популярная библиотека для тестирования React-приложений, ориентированная на поведение компонентов, а не на их внутреннюю реализацию. В React Native она также широко используется для тестирования UI-компонентов, обеспечивая более надежные и читаемые тесты. В отличие от других библиотек для тестирования, таких как Enzyme, RTL акцентирует внимание на том, как компонент ведет себя с точки зрения пользователя, что улучшает поддержку тестов и их реалистичность.
Для начала работы с React Testing Library в проекте React Native необходимо установить несколько зависимостей. Это включает саму библиотеку, а также адаптеры для работы с мобильным окружением.
npm install --save-dev @testing-library/react-native
npm install --save-dev jest
После установки библиотеки следует настроить Jest, который будет выполнять тесты. Для этого можно использовать базовую конфигурацию Jest, которая совместима с React Native. Важно, чтобы Jest был настроен на использование мока для некоторых специфичных для мобильных платформ модулей.
Пример базовой настройки в jest.config.js:
module.exports = {
preset: 'react-native',
setupFiles: ['./jest/setup.js'],
transformIgnorePatterns: [
'node_modules/(?!@react-native|react-native|@react-navigation)'
],
};
Файл setup.js может включать дополнительные настройки
для Jest и RTL.
Для тестирования компонента необходимо его отрендерить. В React
Native это выполняется с помощью функции render из
библиотеки @testing-library/react-native.
Пример:
import { render } from '@testing-library/react-native';
import React from 'react';
import MyComponent from '../MyComponent';
test('Компонент рендерится правильно', () => {
const { getByText } = render(<MyComponent />);
expect(getByText('Привет, мир!')).toBeTruthy();
});
Функция render возвращает набор методов для поиска
элементов в компоненте, таких как getByText,
getByTestId и другие.
React Testing Library предоставляет несколько способов для поиска элементов в рендере компонента:
testID, который может быть установлен для тестирования
компонентов.<label>), что особенно полезно
для формы.Пример использования getByTestId:
test('Поиск элемента по testID', () => {
const { getByTestId } = render(<MyComponent />);
const button = getByTestId('submit-button');
expect(button).toBeTruthy();
});
Для проверки взаимодействий с пользователем RTL предлагает API для
симуляции событий. Например, чтобы нажать кнопку, можно использовать
метод fireEvent.
Пример:
import { render, fireEvent } from '@testing-library/react-native';
import React from 'react';
import MyComponent from '../MyComponent';
test('Клик по кнопке вызывает нужную функцию', () => {
const mockFunction = jest.fn();
const { getByTestId } = render(<MyComponent onPr ess={mockFunction} />);
const button = getByTestId('submit-button');
fireEvent.press(button);
expect(mockFunction).toHaveBeenCalledTimes(1);
});
Метод fireEvent.press используется для симуляции нажатия
на элементы, такие как кнопки или зоны на экране.
Многие мобильные приложения работают с асинхронными действиями,
такими как загрузка данных с сервера или выполнение длительных операций.
React Testing Library поддерживает асинхронные ожидания с помощью
методов, таких как findByText, findByTestId и
waitFor.
Пример асинхронного теста:
import { render, screen, waitFor } from '@testing-library/react-native';
import React from 'react';
import MyComponent from '../MyComponent';
test('Асинхронное обновление текста', async () => {
render(<MyComponent />);
// Ожидаем, что элемент с текстом будет найден через 500 мс
const textElement = await screen.findByText('Данные загружены');
expect(textElement).toBeTruthy();
});
Метод findByText является асинхронным и возвращает
обещание, которое будет разрешено, когда элемент появится в DOM.
waitFor используется для явного ожидания состояния
компонента, пока не произойдут необходимые изменения.
Иногда для тестирования компонентов необходимо использовать моки для внешних зависимостей или сервисов, таких как API-запросы. Это можно сделать с помощью Jest, создавая моки для функций или модулей, которые компонент использует.
Пример мока функции:
jest.mock('axios');
test('Загрузка данных с API', async () => {
axios.get.mockResolvedValue({ data: { message: 'Данные загружены' } });
const { getByText } = render(<MyComponent />);
const textElement = await findByText('Данные загружены');
expect(textElement).toBeTruthy();
});
В этом примере мокаем axios.get, чтобы он возвращал
поддельные данные, что позволяет тестировать компонент, не выполняя
реальные запросы.
React Native включает множество компонентов, с которыми пользователь может взаимодействовать. Эти компоненты могут включать кнопки, текстовые поля, переключатели и другие элементы. Важно протестировать, как они реагируют на действия пользователя.
Пример тестирования поля ввода:
import { render, fireEvent } from '@testing-library/react-native';
import React from 'react';
import MyComponent from '../MyComponent';
test('Изменение текста в поле ввода', () => {
const { getByPlaceholderText } = render(<MyComponent />);
const inputField = getByPlaceholderText('Введите текст');
fireEvent.changeText(inputField, 'Тестовое значение');
expect(inputField.props.value).toBe('Тестовое значение');
});
Здесь мы симулируем ввод текста в поле и проверяем, что значение поля обновилось.
В мобильных приложениях часто используется навигация между экранами.
Для тестирования компонентов с навигацией можно использовать моки из
библиотеки @react-navigation/native и их взаимодействие с
React Testing Library.
Пример использования мока навигации:
import { render } from '@testing-library/react-native';
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import MyComponent from '../MyComponent';
const Stack = createStackNavigator();
test('Навигация между экранами', () => {
const { getByTestId } = render(
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={MyComponent} />
</Stack.Navigator>
</NavigationContainer>
);
const button = getByTestId('navigate-button');
fireEvent.press(button);
// Здесь можно добавить проверку, что навигация произошла
});
Здесь мы тестируем, что нажимая кнопку, происходит переход на другой экран.
getByRole, getByLabelText и другие
методы, которые делают ваш код более доступным и легко читаемым.React Testing Library для React Native позволяет создавать стабильные, поддерживаемые и понятные тесты. Следование основным принципам работы с библиотекой обеспечивает высокое качество кода и уверенность в его правильной работе.