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 — воно показує, які ресурси та таймери наразі очікуються фреймворком.
Після прогону тестів 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також