Detox는 Wix 팀이 React Native 프로젝트를 위해 특별히 만든 모바일 애플리케이션용 gray-box E2E 테스트 프레임워크입니다. black-box 방식과 달리 Detox는 애플리케이션의 내부 상태에 접근할 수 있어 수동 타임아웃 없이 자동으로 동기화할 수 있습니다. Wix Engineering, 2026에 따르면, 자동 동기화는 기존 일시 중지 방식과 비교하여 테스트 실행 시간을 40% 단축합니다.
핵심 사항
Detox는 Wix가 2017년에 개발한 모바일 애플리케이션의 엔드투엔드(E2E) 테스트 프레임워크입니다. 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는 애플리케이션이 다음 단계를 수행할 준비가 되었다고 간주합니다.
동기화는 애플리케이션의 메인 스레드 모니터링을 기반으로 합니다. Detox는 모든 애니메이션이 완료되고, HTTP 요청이 응답을 반환하며, 이벤트 핸들러 실행이 종료될 때까지 기다립니다. 무한 애니메이션으로 인해 테스트가 중단되면 특정 코드 블록에 대해 동기화를 수동으로 비활성화할 수 있습니다.
// 문제가 있는 섹션의 동기화 비활성화
await device.disableSynchronization();
// 긴 애니메이션이 있는 작업
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
Detox 설치는 npm 또는 yarn을 통해 패키지를 추가하는 것으로 시작됩니다. 설치 후 각 플랫폼의 빌드 및 실행 설정을 설명하는 구성 파일 .detoxrc.js를 만들어야 합니다. Detox는 Xcode 구성을 기반으로 iOS용 자체 빌드 유형을 사용합니다.
구성에는 애플리케이션 경로(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 테스트는 요소 검색(matchers) 및 작업(actions)을 기반으로 하는 API를 사용하여 JavaScript 또는 TypeScript로 작성됩니다. Matchers를 사용하면 식별자, 텍스트, 유형 또는 화면 위치로 요소를 찾을 수 있습니다. 작업은 탭, 텍스트 입력, 스와이프 및 스크롤을 수행합니다.
일반적인 테스트는 다음 순서를 따릅니다: 요소 찾기 → 작업 수행 → 결과 확인. 확인을 위해 expect API가 요소의 존재, 가시성 또는 텍스트에 대한 matcher와 함께 사용됩니다. Detox는 Jest와의 통합을 통해 describe/it 구문을 지원합니다.
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는 GitHub Actions, CircleCI, Bitrise, Jenkins 등 인기 있는 CI 시스템과 잘 통합됩니다. CI에서 실행하려면 가상 iOS 시뮬레이터(GUI 없음)와 하드웨어 가속이 포함된 Android 에뮬레이터를 설정해야 합니다. Detox는 실패한 테스트 분석을 위한 아티팩트(스크린샷 및 로그)를 제공합니다.
CI에서 테스트 실행 속도를 높이려면 --workers 플래그와 함께 샤딩(병렬화)을 사용하는 것이 좋습니다. Detox는 자동으로 여러 시뮬레이터에 테스트 파일을 분산합니다. 빌드 시간을 줄이기 위해 실행 간에 애플리케이션 빌드를 캐싱하는 것도 유용합니다.
# GitHub Actions — iOS에서 Detox 실행
- 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 연결에 유용합니다.
각 테스트에 대해 격리된 상태를 만드는 것이 좋습니다. device.reloadReactNative()를 통해 애플리케이션을 다시 로드하려면 beforeEach를 사용하세요. 특정 데이터가 필요한 테스트의 경우 서버에서 데이터를 준비하기 위한 팩토리 또는 API 클라이언트를 만드세요. 테스트 간 종속성을 피하세요 — 각 테스트는 독립적이어야 합니다.
Detox는 web.element() 및 web.invoke() 메서드를 통해 WebView 테스트를 지원합니다. 웹 요소와 상호 작용하려면 by.web](:id, css 또는 className이 사용됩니다. WebView에는 추가 로딩 시간이 필요하다는 점을 기억하는 것이 중요합니다 — 동기화가 작동하지 않으면 waitFor를 사용하여 로딩 대기를 추가하세요.
// Detox에서 WebView 테스트
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는 먼저 iphonesimulator 구성으로 xcodebuild를 통해 애플리케이션을 빌드해야 합니다. 일반적인 실수는 Debug 대신 Release 스킴을 사용하여 테스트 플래그가 비활성화되는 것입니다. Android의 경우 AVD가 애플리케이션과 호환되는 API로 생성되었는지, Intel HAXM 가속이 활성화되었는지 확인하세요. macOS의 CI 환경에서는 Xcode와 시뮬레이터가 이미 사전 설치된 macOS 러너로 GitHub Actions를 사용하는 것이 편리합니다.
테스트가 정기적으로 시간 초과로 실패하는 경우 다음을 확인하세요: 동기화가 전역적으로 비활성화되어 있는지, 애플리케이션 코드에서 setTimeout 또는 setInterval이 정리 없이 사용되고 있는지, 메인 스레드가 긴 작업으로 차단되고 있는지. 때로는 detoxrc.js에서 testRunner.args.jest.$.testTimeout을 통해 시간 초과를 늘리는 것이 도움이 됩니다. 문제 영역을 찾으려면 Detox 추적 로깅을 활성화하세요 — 프레임워크가 현재 어떤 리소스와 타이머를 기다리고 있는지 보여줍니다.
테스트 실행 후 Detox는 아티팩트(실패한 테스트의 스크린샷, 애플리케이션 로그, JUnit XML 보고서)를 생성합니다. 스크린샷은 테스트 실패 시 자동으로 촬영되며 문제를 시각적으로 식별하는 데 도움이 됩니다. CI의 경우 아티팩트는 클라우드 스토리지에 업로드되어 웹 인터페이스를 통해 실패 원인 분석에 사용할 수 있습니다.
자주 묻는 질문
Detox는 애플리케이션의 내부 상태에 접근하고 자동 동기화하는 gray-box 접근 방식을 사용합니다. Appium은 WebDriver를 통한 black-box 모델로 작동하며 수동 대기가 필요합니다. React Native 프로젝트의 경우 Detox가 더 빠르고 안정적입니다.
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의 메서드로, 애플리케이션을 재설치하지 않고 React Native JavaScript 번들을 다시 로드합니다. 각 테스트 전에 애플리케이션 상태를 초기 화면으로 재설정하기 위해 beforeEach에서 사용됩니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.