Олег Марков
Где искать elements для приложения на React Native
Введение
Работая с React Native, вы часто сталкиваетесь с задачей поиска элементов пользовательского интерфейса для автоматизации тестирования или для динамического взаимодействия прямо из кода. Разработчикам нужно уметь надежно находить элементы для UI-тестов, e2e-тестирования (например, с использованием Detox), решения задач автоматизации и даже для операций вроде модального управления или динамической стилизации компонентов. Чтобы упростить эти задачи, важно понять, какие подходы поиска существуют, как работать с идентификаторами и что делать, если стандартных решений не хватает.
Эта статья отвечает на главный вопрос: где и как искать элементы (elements) в приложениях на React Native? Сюда входит разбор способов поиска через тестовые идентификаторы (testID
), работу с инструментами для автотестирования, а также базовые техники поиска элементов через React Native API.
Основные способы поиска элементов в React Native
Поиск элементов через testID
В React Native любое View-подобное представление (например, Button, Text, TouchableOpacity) может иметь свойство testID
. Это стандартный и официальный способ помечать элементы для поиска во время автоматического или ручного тестирования.
Вот простой пример:
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
const MyComponent = () => (
<View>
<Text testID="welcome-text">Добро пожаловать!</Text>
<TouchableOpacity testID="login-button">
<Text>Войти</Text>
</TouchableOpacity>
</View>
);
export default MyComponent;
Здесь testID
задается для компонентов, чтобы их легко найти в тестах. Для библиотеки Detox поиск по testID выглядит так:
// Находим элемент с testID = login-button и нажимаем на него
await element(by.id('login-button')).tap();
Поиск подходящих элементов и ресурсов - важная часть разработки любого приложения. В React Native существует множество ресурсов, где можно найти готовые компоненты, иконки, шрифты и другие элементы для вашего приложения. Чтобы ускорить процесс разработки и создавать привлекательные интерфейсы, важно знать, где искать эти ресурсы и как их правильно использовать. Если вы хотите детально разобраться в поиске элементов для React Native приложений и научиться эффективно использовать готовые ресурсы — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Особенности и рекомендации testID
- Используйте уникальные значения для testID в рамках одного экрана.
- Не смешивайте testID с ключами props (например, key) – они для разных целей.
- Добавлять testID лучше на те элементы, которые должны участвовать в тестах, а не на все подряд.
Использование label для Universal Access и тестирования
React Native поддерживает проп accessibilityLabel
— он нужен для доступности, но также используется как дополнительный путь поиска элементов (особенно в iOS):
<TouchableOpacity
accessibilityLabel="Кнопка входа"
testID="login-button"
>
<Text>Войти</Text>
</TouchableOpacity>
- В автоматизированных тестах на iOS
accessibilityLabel
можно использовать для поиска элемента средствами UI-тестирования. - На Android предпочтителен
testID
, но в некоторых библиотеках возможно использовать и label.
Поиск элементов через текст
Многие тестовые фреймворки позволяют искать элементы по тексту, который отображается пользователю. Это полезно, если вы не добавили testID, но текст гарантированно уникален.
Пример с использованием Detox:
await element(by.text('Войти')).tap();
- Такой подход удобен, но может перестать работать, если тексты меняются часто (например, при локализации).
Поиск элементов через структуру дерева и селекторы
Если не задан testID
, можно обращаться к элементам по иерархии, используя путь к нужному компоненту (например, в End-to-End тестах или при отладке):
// Используем by.type, если testID нет
await element(by.type('RCTText')).atIndex(1);
by.type
позволяет искать все элементы определенного типа.- Метод
atIndex(n)
помогает выбрать нужный экземпляр (если их несколько).
Поиск элементов в unit-тестах с React Native Testing Library
В unit-тестах обычно используют React Native Testing Library (RNTL). Она поддерживает удобные методы поиска:
import { render } from '@testing-library/react-native';
const { getByTestId, getByText } = render(<MyComponent />);
getByTestId('login-button'); // Находит элемент по testID
getByText('Войти'); // Находит по тексту, видимому пользователю
- Методы поиска включают:
getByTestId
,getByText
,queryByText
,findByText
, и их производные. - Помните, что метод
getByTestId
выбрасывает ошибку, если элемент не найден.
Общие рекомендации по добавлению идентификаторов для поиска
Где и как размещать testID
- Старайтесь размещать testID только на ключевых для логики и UX элементах.
- Придерживайтесь единой схемы именования, например:
screenName-element-action
(login-email-input). - Помещайте testID в props именно того компонента, с которым работает пользователь (не всегда нужен на обертках типа View).
Использование констант
Чтобы избежать опечаток, можно хранить testID в отдельном файле:
// testIDs.js
export const TEST_IDS = {
LOGIN_BUTTON: 'login-button',
EMAIL_INPUT: 'login-email-input'
};
// Применение
<TextInput testID={TEST_IDS.EMAIL_INPUT} />
<TouchableOpacity testID={TEST_IDS.LOGIN_BUTTON}>
Как найти элементы без testID
Нет testID — ищите по:
- Тексту (
getByText
,by.text
) - Типу компонента (
by.type
) - Селектору (например, для e2e можно пытаться искать по структуре)
- accessibilityLabel (особенно важно для доступности)
Однако лучше всегда использовать testID или добавлять его при необходимости.
Пример: создание тестового идентификатора по условию
Бывает, что testID должен появляться только в определенных условиях (например, в debug-сборке). Это делается просто:
<TouchableOpacity
testID={__DEV__ ? 'button-debug' : undefined}
>
<Text>Debug Кнопка</Text>
</TouchableOpacity>
- Используйте константы типа
__DEV__
, чтобы не добавлять идентификаторы в production.
Использование инструментов и утилит для поиска elements
Инспекторы интерфейса
- React Native Debugger позволяет инспектировать дерево элементов, смотреть пропсы и testID прямо из отладки.
- Detox devtools и утилиты Appium помогают просматривать и искать элементы в реальном приложении, подбирая нужные свойства для поиска.
Поиск с помощью тестовых инструментов
- Detox (
element(by.id('testID'))
) — для e2e на React Native. - Appium — может использовать
accessibilityLabel
и testID для автоматизации. - Jest + RNTL — тесты юнитов, поиск через getByTestId.
Как обеспечивать тестируемость при проектировании компонентов
- Проектируйте компоненты так, чтобы у каждого интерактивного элемента был testID.
- Не кладите тестовые идентификаторы на View без смысла — пометьте только значимые контролы (кнопки, инпуты, чекбоксы).
- Вынесите testID и accessibilityLabel в props компонента, если планируете переиспользование:
const CustomButton = ({ onPress, label, testID }) => (
<TouchableOpacity onPress={onPress} testID={testID}>
<Text>{label}</Text>
</TouchableOpacity>
);
- Передавайте testID снаружи, особенно если компонент универсален.
Роль структуры дерева компонентов при поиске
- Иногда приходится искать элемент по вложенности — старайтесь сохранять разумную глубину для тестируемых компонентов и помнить, что глубокие вложенности усложняют тесты.
- Не зависите только от визуального положения — структура канваса может меняться, лучше использовать идентификаторы.
Поддержка поиска на разных платформах
- На Android props
testID
трансформируется вresource-id
с помощью модуля React Native. - На iOS используется как часть accessibilityLabel.
- Убедитесь, что в ваших тестах поиск универсален: если пишете кроссплатформенно — проверьте оба пути.
Как искать элементы при использовании сторонних библиотек (например, UI Kit)
Если используете UI-библиотеки (например, React Native Paper, NativeBase):
- Некоторые компоненты уже поддерживают testID — всегда загляните в их документацию.
- В случае отсутствия поддержки можно обернуть компонент своим, прокинув testID вручную.
Пример обертки:
// Для компонента-кнопки из библиотеки
const PaperButtonWithTestID = ({ testID, ...props }) => (
<Button {...props} testID={testID} />
);
Теперь можно легко искать элемент по testID в автотестах.
Заключение
Выяснять, где искать и как помечать элементы в приложениях на React Native, — ключевая часть процесса разработки и тестирования. Наиболее надежный и рекомендованный метод — добавлять testID
к нужным элементам интерфейса, особенно к кнопкам, полям ввода и важным для сценария взаимодействия компонентам. Это позволит быстро и точно находить их с помощью инструментов автоматизации или юнит-тестирования.
Если по каким-то причинам вы не можете использовать testID, обращайте внимание на варианты поиска по accessibilityLabel
, тексту, типу компонента или структуре дерева. Чтобы обеспечить удобство в долгосрочной перспективе, формируйте единый стиль именования, а также старайтесь добавлять тестовые идентификаторы на этапе проектирования компонентов.
Поиск элементов - это важный, но не единственный аспект разработки качественного React Native приложения. Для создания полноценного приложения необходимо освоить множество других технологий и подходов, включая работу с UI, данными и нативными функциями. Курс React Native и Expo Router поможет вам в этом. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Как искать элементы в модальных или всплывающих окнах?
Иногда элементы в модалках не ищутся стандартным способом (например, компонент Modal создает отдельный слой). В таком случае ищите элементы с тестовыми идентификаторами (testID
), следя за тем, чтобы modal был открыт во время теста. Также полезно использовать waitFor()
в тестах, чтобы дождаться появления элемента:
await waitFor(() => expect(getByTestId('my-modal-element')).toBeTruthy());
Почему в некоторых случаях testID
не работает на Android?
React Native иногда неправильно прокидывает testID на нативные слои, особенно для сторонних компонентов. Убедитесь, что используемый компонент поддерживает передачу testID до уровня native. Если нет — рассмотрите создание собственной обертки или поиск по другим свойствам.
Можно ли динамически изменить testID у элемента?
Да — testID это такой же prop, как и любой другой, его можно менять через состояние или пропсы:
<MyButton testID={isPressed ? 'pressed-id' : 'default-id'} />
Главное — не усложнять структуру, если нет острой необходимости.
Как добавить testID или accessibilityLabel
в компонент, если библиотека этого не поддерживает?
Создайте собственную обертку над компонентом и пробросьте нужные props вручную. Либо, если компонент поддерживает другие идентифицирующие props (например, nativeID
), используйте их совместно с тестовым инструментом.
Как работать с элементами, которые появляются с задержкой (асинхронно)?
Для асинхронных UI-операций пользуйтесь ожиданиями из тестового фреймворка — например, ждите появления элемента через waitFor
или эквивалентные методы, прежде чем взаимодействовать с ним:
await waitFor(() => expect(getByTestId('async-element')).toBeTruthy());
Постройте личный план изучения React-native до уровня Middle — бесплатно!
React-native — часть карты развития Mobile
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React-native
Лучшие курсы по теме

React Native и Expo Router
Антон Ларичев
Основы JavaScript
Антон Ларичев