E2E-тестування React Native: налаштування Detox і CI
Ви запускаєте CI, а тести падають на рівному місці — то анімація не дочекалася, то елемент не знайдено. Знайомо? Один із наших клієнтів — FinTech-додаток з 50 екранами — страждав від 30% flaky-падінь на кожну збірку. Розробники витрачали години на перезапуски, а релізи затримувалися на тижні. Після впровадження Detox ми знизили відсоток падінь до 5% і скоротили час прогону в 3 рази за рахунок паралельного запуску. Detox — gray-box фреймворк, який вбудовує тест-сервер прямо в процес додатку. На відміну від Appium, Detox автоматично синхронізується з event loop React Native, що дає стабільні тести без sleep(). Це особливо важливо для проєктів з динамічними анімаціями та частими мережевими запитами. Наш досвід — 5+ років і понад 15 реалізованих проєктів — дозволяє гарантувати стабільність тестів навіть на складних UI.
Чому Detox, а не Appium?
| Критерій | Detox | Appium |
|---|---|---|
| Тип доступу | Gray-box (вбудований сервер) | Black-box (зовнішній) |
| Синхронізація | Автоматична з JS-потоком | Вимагає sleep() та очікувань |
| Стабільність на RN | Висока | Низька (часто падають) |
| Підтримка анімацій | Вбудована | Через очікування |
| Швидкість виконання | Швидше | Повільніше через затримки |
| Відсоток flaky на CI | 5-10% | 30-50% |
Ми використовуємо Detox, тому що це єдиний фреймворк, який розуміє внутрішню роботу React Native. Результат — тести, які не падають на рівному місці в CI.
Як ми конфігуруємо Detox: перші граблі
Налаштування Detox займає більше часу, ніж здається. Особливо на iOS. Ось конфігурація, яку ми використовуємо за замовчуванням:
{ "detox": { "testRunner": { "args": { "$0": "jest", "config": "e2e/jest.config.js" }, "jest": { "setupTimeout": 120000 } }, "apps": { "ios.debug": { "type": "ios.app", "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/MyApp.app", "build": "xcodebuild -workspace ios/MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build" }, "android.debug": { "type": "android.apk", "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug" } }, "devices": { "simulator": { "type": "ios.simulator", "device": { "type": "iPhone 15", "os": "iOS 17.4" } }, "emulator": { "type": "android.emulator", "device": { "avdName": "Pixel_7_API_34" } } } } } Часта проблема: APK має бути зібраний з assembleAndroidTest — інакше синхронізація не працює. На iOS — тільки симулятор білд (-sdk iphonesimulator). Реальні пристрої вимагають окремого профілювання та signing. Також важливо налаштувати setupTimeout — для великих проєктів ми ставимо 120 секунд, щоб тести встигли ініціалізуватися.
Як уникнути flaky-тестів?
Flaky-тести — головний біль CI. Detox знижує їх кількість, але повністю не виключає. Ось таблиця з типовими причинами та рішеннями:
| Причина | Рішення |
|---|---|
| Анімації зациклені | Вимкнути в test build через прапорець detoxDisableHierarchyDump або кастомний IS_TESTING |
| Мережеві запити не завершені | Використовувати waitFor з таймаутом, або перехоплювати запити через mock |
| Стан екрану не скинуто | Викликати device.reloadReactNative() перед кожним тестом |
| Таймаути Jest недостатні | Збільшити jest.setTimeout до 120 секунд |
| Різні версії iOS/Android | Тестувати на тих же версіях, що і в CI |
Також використовуємо угоду щодо testID: screen_component_action. Це спрощує підтримку та пошук елементів.
Паралельне тестування: як прискорити CI?
Detox підтримує паралельний запуск через шардування Jest. Команда:
detox test --configuration android.debug --workers 3 Вимагає 3 емулятори або симулятори. На macOS потрібно 16 ГБ RAM для 3 симуляторів. AVD створюються автоматично за наявності прав. Паралельний запуск скорочує час повного прогону з 45 хвилин до 15 хвилин — у 3 рази швидше.
Інтеграція в CI: рецепт для GitHub Actions
Для iOS використовуємо macOS-ранер, для Android — ubuntu разом із reactivecircus/android-emulator-runner. Приклад збірки та тестів:
jobs: e2e-ios: runs-on: macos-14 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - run: npm ci - run: npx pod-install - run: npx detox build --configuration ios.debug - run: npx detox test --configuration ios.debug --headless Для Android — обов'язковий --headless, інакше емулятор не знайде дисплей. Також варто кешувати симулятори та емулятори, щоб не створювати їх заново.
Типові команди Detox для налагодження
-
detox test —reuse— перевикористовувати вже запущений пристрій. -
detox test —record-logs all— записати логи всіх тестів. -
detox build —configuration ios.debug 2>&1 | tee build.log— зберегти лог збірки. -
detox test —debug— запустити з дебаг-режимом.
Що входить у роботу
- Повна конфігурація Detox під iOS і Android
- Написання тестів для ключових користувацьких флоу (авторизація, навігація, платежі)
- Документація з налаштування та розширення тестів
- Інтеграція у ваш CI/CD (GitHub Actions, GitLab CI, Jenkins)
- Навчання команди (2 години + доступ до запису)
- Гарантія стабільності тестів: не більше 5% flaky-падінь
Строки та вартість
Базове налаштування конфігурації та покриття основних флоу займає 5 днів. За наявності складних нативних модулів (push-сповіщення, біометрія, камера) — до 7 днів. Вартість розраховується індивідуально — напишіть нам, і ми проаналізуємо ваш додаток та запропонуємо оптимальний план.
Ми гарантуємо стабільність тестів на всіх етапах. Звертайтеся — допоможемо вашій команді забути про flaky-тести та прискорити релізний цикл. Отримайте консультацію: надішліть заявку, і ми зв'яжемося з вами протягом дня.







