Detox — это фреймворк для gray-box E2E-тестирования мобильных приложений, созданный командой Wix специально для React Native проектов. В отличие от black-box подходов, Detox имеет доступ к внутреннему состоянию приложения, что позволяет автоматически синхронизироваться с ним без ручных таймаутов. По данным Wix Engineering, 2026, автоматическая синхронизация сокращает время прогона тестов на 40% по сравнению с традиционными паузами.
Главное
Detox — это фреймворк для сквозного (E2E) тестирования мобильных приложений, разработанный компанией Wix в 2017 году. Он предназначен для React Native проектов, но поддерживает и чисто нативные приложения на iOS и Android. Detox работает по gray-box модели, что означает наличие доступа к внутренним механизмам приложения.
Главное отличие Detox от Appium или Calabash — это автоматическая синхронизация с приложением. Фреймворк ожидает завершения анимаций, сетевых запросов и обработки событий, прежде чем выполнять следующее действие. Это полностью устраняет необходимость в Thread.sleep() или waitForElement, которые замедляют тесты.
Detox поддерживает iOS (через XCTest и Xcode) и Android (через Espresso и UI Automator). Для React Native приложений обеспечивается полная поддержка Fabric и старой архитектуры. На iOS тесты запускаются на симуляторе, на Android — на эмуляторе или реальном устройстве.
Архитектура Detox состоит из трёх ключевых компонентов: Detox CLI, Detox тест-раннера и Detox Native Driver. Detox CLI управляет сборкой приложения, установкой и запуском тестов. Тест-раннер (Jest или Mocha) выполняет тестовые сценарии и взаимодействует с приложением через WebSocket.
Gray-box тестирование означает, что Detox имеет доступ к внутреннему состоянию приложения через нативный мост. Фреймворк отслеживает сетевые запросы, анимации, таймеры и очередь операций. Когда все очереди пусты — Detox считает приложение готовым к следующему шагу.
Синхронизация основана на отслеживании основного потока (main thread) приложения. Detox ожидает, пока все анимации завершатся, HTTP-запросы вернут ответ и обработчики событий выполнятся. Если тест зависает из-за бесконечной анимации — можно принудительно отключить синхронизацию для конкретного блока кода.
// Отключение синхронизации для проблемного участка
await device.disableSynchronization();
// Действие с длительной анимацией
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
Установка Detox начинается с добавления пакета через npm или yarn. После установки требуется создать конфигурационный файл .detoxrc.js, в котором описываются настройки сборки и запуска для каждой платформы. Detox использует собственный билд-тайп для iOS, основанный на конфигурации Xcode.
Конфигурация включает путь к приложению (app), тип билдера (build), аргументы сборки и настройки устройства (device). Для iOS используется appleSimulator, для Android — androidEmulator. Также можно указать аргументы запуска, такие как язык или регион симулятора.
// .detoxrc.js — пример конфигурации
module.exports = {
testRunner: { args: { '$0': 'jest', config: 'e2e/config.json' } },
apps: {
'ios.debug': { type: 'ios.app', build: 'xcodebuild ...' },
'android.debug': { type: 'android.apk', build: 'cd android && ./gradlew ...' }
},
devices: {
simulator: { type: 'ios.simulator', device: { type: 'iPhone 15' } },
emulator: { type: 'android.emulator', device: { avdName: 'Pixel_4_API_34' } }
}
};
После конфигурации доступны команды: detox build — сборка приложения с флагами для тестирования, и detox test — запуск тестов. Detox поддерживает параллельный запуск на нескольких устройствах через флаг --workers.
Тесты Detox пишутся на JavaScript или TypeScript с использованием API, основанном на поиске элементов (matchers) и действиях (actions). Matchers позволяют найти элемент по идентификатору, тексту, типу или положению на экране. Actions выполняют нажатие, ввод текста, свайп и скролл.
Типичный тест выглядит как последовательность: найти элемент → выполнить действие → проверить результат. Для проверок используется expect-API с matchers по наличию, видимости или тексту элемента. Detox поддерживает describe/it-синтаксис через интеграцию с Jest.
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should log in with valid credentials', async () => {
await element(by.id('emailInput')).typeText('user@test.com');
await element(by.id('passwordInput')).typeText('password123');
await element(by.id('loginButton')).tap();
await expect(element(by.id('homeScreen'))).toBeVisible();
});
});
Detox поддерживает все популярные жесты: tap, longPress, swipe, scroll, pinch, multiTap. Для scroll можно указать направление, скорость и позицию остановки. Это позволяет тестировать сложные сценарии, например, pull-to-refresh или карусели.
Detox хорошо интегрируется с популярными CI-системами: GitHub Actions, CircleCI, Bitrise и Jenkins. Для запуска в CI требуется настроить виртуальный симулятор iOS (без GUI) и Android-эмулятор с аппаратным ускорением. Detox предоставляет артефакты — скриншоты и логи — для анализа упавших тестов.
Для ускорения прогона тестов в CI рекомендуется использовать шардирование (parallelization) с флагом --workers. Detox автоматически распределяет тестовые файлы между несколькими симуляторами. Также полезно кэшировать билды приложения между запусками для сокращения времени сборки.
# GitHub Actions — запуск Detox на iOS
- name: Install Dependencies
run: npm ci
- name: Build Detox App
run: npx detox build --configuration ios.sim
- name: Run Detox Tests
run: npx detox test --configuration ios.sim --workers 2
timeout-minutes: 30
Для стабильных и быстрых E2E-тестов рекомендуется соблюдать несколько правил. Избегайте sleep() — Detox предоставляет автоматическую синхронизацию, и явные задержки только замедляют тесты и делают их нестабильными. Если тест падает из-за таймингов, сначала проверьте, не отключена ли синхронизация. Также полезно группировать тесты по фичам и запускать их независимо — это упрощает поиск причины падения.
Detox предоставляет несколько методов device для управления состоянием: device.reloadReactNative() перезагружает бандл, device.launchNewApp() запускает приложение с новыми параметрами, device.sendToHome() сворачивает приложение. device.setURLBlacklist() позволяет исключить определённые URL из синхронизации, что полезно для аналитики и long-polling соединений.
Для каждого теста рекомендуется создавать изолированное состояние. Используйте beforeEach для перезагрузки приложения через device.reloadReactNative(). Для тестов, требующих специфических данных, создавайте фабрики или API-клиенты для подготовки данных на сервере. Избегайте зависимостей между тестами — каждый тест должен быть независимым.
Detox поддерживает тестирование WebView через методы web.element() и web.invoke(). Для взаимодействия с веб-элементами используется by.web](:id, css или className. Важно помнить, что WebView требует дополнительного времени на загрузку — если синхронизация не работает, добавьте ожидание загрузки через waitFor.
// Тестирование WebView в Detox
const webView = web(by.id('webview'));
await webView.element(by.web.cssSelector('#submit-btn')).tap();
const result = await webView.element(
by.web.cssSelector('.result-text')
).getText();
await expect(result).toEqual('Success');
Detox поддерживает сравнение скриншотов через плагин detox-image-matching. Снимки экрана позволяют обнаружить визуальные регрессии: смещённые элементы, неверные цвета, отсутствующие иконки. Для стабильных скриншотов отключайте анимации и используйте фиксированный размер симулятора.
Наиболее частые проблемы Detox связаны с синхронизацией: бесконечные анимации, длинные сетевые запросы или зависшие таймеры. Логирование с флагом --loglevel trace показывает, какие ресурсы ожидает Detox. Если Detox зависает — используйте device.disableSynchronization() для проблемного участка кода.
На iOS симуляторе Detox требует предварительной сборки приложения через xcodebuild с конфигурацией iphonesimulator. Частая ошибка — использование Release-схемы вместо Debug, что отключает флаги тестирования. Для Android убедитесь, что AVD создан с API, совместимым с вашим приложением, и ускорение Intel HAXM включено. Для CI-окружений на macOS удобно использовать GitHub Actions с macOS-раннером, где Xcode и симуляторы уже предустановлены.
Если тесты регулярно падают по таймауту, проверьте: не отключена ли синхронизация глобально, не используются ли setTimeout или setInterval в коде приложения без очистки, и не блокирует ли основной поток длительная операция. Иногда помогает увеличить таймаут в detoxrc.js через testRunner.args.jest.$.testTimeout. Для поиска проблемных участков включите трассировочное логирование Detox — оно показывает, какие ресурсы и таймеры currently ожидаются фреймворком.
После прогона тестов Detox создаёт артефакты: скриншоты упавших тестов, логи приложения и XML-отчёты JUnit. Скриншоты делаются автоматически при падении теста и помогают визуально определить проблему. Для CI артефакты загружаются в облачное хранилище и доступны через веб-интерфейс для анализа причин падения.
Часто задаваемые вопросы
Detox использует gray-box подход с доступом к внутреннему состоянию приложения и автоматической синхронизацией. Appium работает по black-box модели через WebDriver и требует ручных ожиданий. Detox быстрее и стабильнее для React Native проектов.
Тесты Detox пишутся на JavaScript или TypeScript. Фреймворк интегрируется с Jest и Mocha в качестве тест-раннеров. Нативный движок для iOS написан на Swift, для Android — на Kotlin и Java.
Да, Detox поддерживает нативные приложения на iOS (через XCTest) и Android (через Espresso). Однако основная аудитория Detox — React Native разработчики, поскольку для нативных проектов существуют более зрелые решения.
Detox предоставляет артефакты: скриншоты экрана, логи приложения и HTML-отчёты. Для локальной отладки используется флаг --loglevel trace, а для CI — автоматический артефакт-коллектор с загрузкой в облако.
Это метод Detox API, который перезагружает JavaScript-бандл React Native приложения без переустановки. Он используется в beforeEach для сброса состояния приложения к начальному экрану перед каждым тестом.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также