Detox: 概要、動作原理、E2Eテスト

著者: IT Sectr 公開日: 2026-04-09 読了時間: 8 分

Detoxは、WixチームがReact Nativeプロジェクト向けに作成したモバイルアプリケーションのgray-box E2Eテストフレームワークです。black-boxアプローチとは異なり、Detoxはアプリケーションの内部状態にアクセスできるため、手動のタイムアウトなしで自動的に同期できます。Wix Engineering, 2026によると、自動同期により、従来の一時停止と比較してテスト実行時間が40%短縮されます。

重要なポイント

  • Detox — React Nativeおよびネイティブアプリケーション向けgray-box E2Eフレームワーク
  • 自動同期により、手動の遅延やsleep呼び出しが不要になります
  • テストはmatcherおよびaction APIを使用してJavaScriptまたはTypeScriptで記述します
  • 実行はiOSシミュレータ、Androidエミュレータ、または実機で可能です
  • CI/CD統合はDetox CLIと設定ファイルを介して行われます

Detoxとは

Detoxは、Wixが2017年に開発したモバイルアプリケーションのエンドツーエンド(E2E)テストフレームワークです。React Nativeプロジェクト向けに設計されていますが、iOSおよびAndroidの純粋なネイティブアプリケーションもサポートしています。Detoxはgray-boxモデルで動作し、アプリケーションの内部メカニズムにアクセスできることを意味します。

他のE2Eフレームワークとの違い

DetoxとAppiumやCalabashの主な違いは、アプリケーションとの自動同期です。フレームワークは、次のアクションを実行する前に、アニメーション、ネットワークリクエスト、イベント処理の完了を待機します。これにより、テストを遅くするThread.sleep()やwaitForElementが完全に不要になります。

サポートされるプラットフォーム

DetoxはiOS(XCTestおよびXcode経由)とAndroid(EspressoおよびUI Automator経由)をサポートしています。React Nativeアプリケーションについては、Fabricおよび旧アーキテクチャの完全サポートが提供されています。iOSではシミュレータで、Androidではエミュレータまたは実機でテストを実行します。

Detoxのアーキテクチャとgray-boxモデル

Detoxのアーキテクチャは、Detox CLI、Detoxテストランナー、Detox Native Driverの3つの主要コンポーネントで構成されています。Detox CLIは、アプリケーションのビルド、インストール、テスト実行を管理します。テストランナー(JestまたはMocha)はテストシナリオを実行し、WebSocketを介してアプリケーションと通信します。

Gray-boxアプローチ

Gray-boxテストとは、Detoxがネイティブブリッジを介してアプリケーションの内部状態にアクセスできることを意味します。フレームワークはネットワークリクエスト、アニメーション、タイマー、操作キューを監視します。すべてのキューが空になると、Detoxはアプリケーションが次のステップの準備ができたと見なします。

同期メカニズム

同期はアプリケーションのメインスレッドの監視に基づいています。Detoxは、すべてのアニメーションが完了し、HTTPリクエストが応答を返し、イベントハンドラの実行が終了するまで待機します。無限アニメーションのためにテストがハングした場合は、特定のコードブロックの同期を手動で無効にすることができます。

javascript
// 問題のあるセクションの同期を無効にする
await device.disableSynchronization();
// 長いアニメーションを伴うアクション
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();

Detoxのインストールと設定

Detoxのインストールは、npmまたはyarnを介してパッケージを追加することから始まります。インストール後、各プラットフォームのビルドおよび実行設定を記述する設定ファイル.detoxrc.jsを作成する必要があります。DetoxはXcode設定に基づいて、iOS用の独自のビルドタイプを使用します。

基本設定

設定には、アプリケーションへのパス(app)、ビルダータイプ(build)、ビルド引数、デバイス設定(device)が含まれます。iOSにはappleSimulator、AndroidにはandroidEmulatorが使用されます。シミュレータの言語や地域などの起動引数も指定できます。

javascript
// .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でのテスト作成

Detoxテストは、要素検索(matchers)とアクション(actions)に基づくAPIを使用してJavaScriptまたはTypeScriptで記述します。Matchersを使用すると、識別子、テキスト、タイプ、画面上の位置で要素を見つけることができます。アクションはタップ、テキスト入力、スワイプ、スクロールを実行します。

テストシナリオの構造

典型的なテストは次の順序に従います:要素を見つける → アクションを実行する → 結果を検証する。検証には、expect APIが要素の存在、可視性、テキストのmatchersとともに使用されます。DetoxはJestとの統合によりdescribe/it構文をサポートしています。

javascript
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では、方向、速度、停止位置を指定できます。これにより、プル・トゥ・リフレッシュやカルーセルなどの複雑なシナリオをテストできます。

CI/CDへのDetox統合

DetoxはGitHub Actions、CircleCI、Bitrise、Jenkinsなどの人気CIシステムとよく統合します。CIで実行するには、仮想iOSシミュレータ(GUIなし)とハードウェアアクセラレーション付きのAndroidエミュレータを設定する必要があります。Detoxは失敗したテストを分析するためのアーティファクト(スクリーンショットとログ)を提供します。

CIの推奨事項

CIでのテスト実行を高速化するには、--workersフラグを使用したシャーディング(並列化)をお勧めします。Detoxは自動的にテストファイルを複数のシミュレータに分散します。ビルド時間を短縮するために、実行間でアプリケーションビルドをキャッシュすることも有効です。

yaml
# 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

Detoxのベストプラクティス

安定した高速なE2Eテストのために、いくつかのルールに従うことをお勧めします。sleep()を避ける — Detoxは自動同期を提供しており、明示的な遅延はテストを遅くし、不安定にするだけです。タイミングの問題でテストが失敗する場合は、まず同期が無効になっていないか確認してください。テストを機能ごとにグループ化し、独立して実行することも有効です — これにより失敗の原因を見つけやすくなります。

Deviceメソッドの使用

Detoxは状態管理のためのいくつかのdeviceメソッドを提供しています:device.reloadReactNative()はバンドルを再ロード、device.launchNewApp()は新しいパラメータでアプリケーションを起動、device.sendToHome()はアプリケーションを最小化します。device.setURLBlacklist()を使用すると、特定のURLを同期から除外できます。これは分析やlong-polling接続に便利です。

テストデータの整理

各テストについて、分離された状態を作成することをお勧めします。device.reloadReactNative()を使用してアプリケーションをリロードするには、beforeEachを使用してください。特定のデータが必要なテストの場合は、サーバー上でデータを準備するためのファクトリやAPIクライアントを作成します。テスト間の依存関係を避けてください — 各テストは独立している必要があります。

WebViewの操作

Detoxはweb.element()およびweb.invoke()メソッドを介したWebViewテストをサポートしています。Web要素との対話には、by.web](:id、css、またはclassNameが使用されます。WebViewには追加の読み込み時間が必要であることを覚えておくことが重要です — 同期が機能しない場合は、waitForを使用して読み込み待機を追加してください。

javascript
// 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の問題診断

最も一般的な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では、アーティファクトはクラウドストレージにアップロードされ、Webインターフェースを介して失敗原因の分析に利用できます。

よくある質問

DetoxとAppiumの違いは何ですか?

Detoxはアプリケーションの内部状態へのアクセスと自動同期を備えたgray-boxアプローチを使用します。AppiumはWebDriverを介したblack-boxモデルで動作し、手動待機が必要です。React NativeプロジェクトではDetoxの方が高速で安定しています。

Detoxはどの言語をサポートしていますか?

DetoxテストはJavaScriptまたはTypeScriptで記述します。フレームワークはテストランナーとしてJestおよびMochaと統合します。iOSのネイティブエンジンはSwift、AndroidはKotlinとJavaで記述されています。

Detoxはネイティブアプリケーションに使用できますか?

はい、DetoxはiOS(XCTest経由)およびAndroid(Espresso経由)のネイティブアプリケーションをサポートしています。ただし、Detoxの主なユーザーはReact Native開発者であり、ネイティブプロジェクトにはより成熟したソリューションが存在します。

失敗したDetoxテストをデバッグするには?

Detoxはアーティファクト(スクリーンショット、アプリケーションログ、HTMLレポート)を提供します。ローカルデバッグには--loglevel traceフラグを、CIにはクラウドアップロード付きの自動アーティファクトコレクターを使用してください。

device.reloadReactNativeとは?

これはDetox APIのメソッドで、アプリケーションを再インストールせずにReact NativeのJavaScriptバンドルを再ロードします。beforeEachで使用され、各テストの前にアプリケーションの状態を初期画面にリセットします。

まとめ

  • Detox — React NativeおよびネイティブアプリケーションをテストするためのWix製gray-box E2Eフレームワーク
  • 自動同期により手動タイムアウトが不要になり、テストがより安定します
  • アーキテクチャはCLI、テストランナー、WebSocket接続のネイティブドライバーで構成
  • テストはmatcher、action、expect APIを使用してJavaScriptで記述
  • セットアップには.detoxrc.jsの設定とシミュレータの構成が必要
  • CI/CDはシャーディング、アーティファクト、複数デバイスでの並列実行をサポート
  • Gray-boxアプローチによりアプリケーションの内部状態と操作キューへのアクセスを提供

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください