Expo で detox を動かす(iOS)

ライブラリをインストール

コピーしました!

shell
npm i detox-cli --global

コピーしました!

shell
npm i --save-dev detox @config-plugins/detox jest-expo jest ts-node

app.json の plugin に detox の設定を追加します。

コピーしました!

app.json
    "plugins": [
      "expo-router",
      "@config-plugins/detox"
    ],

次に prebuild コマンドを実行します。

コピーしました!

shell
npx expo prebuild

コピーしました!

shell
detox init

.detoxrc.jsYOUR_APP になっている部分を修正します。 ios ディレクトリ以下のアプリ名に合わせます。

この辺は ios ディレクトリ以下を見ればわかります。

package.json の scripts に以下のような detox コマンドを追加します。

コピーしました!

package.json
    "scripts": {
    "start": "expo start",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web",
    "test": "jest --watchAll",
    "detox:build": "detox build --configuration ios.sim.release",
    "detox:test": "detox test --configuration ios.sim.release"
  },

次に e2e/jest.config.ts を以下のように設定します。デフォルトで作られる e2e/jest.config.jsts に書き換えてOKです。

コピーしました!

e2e/jest.config.ts
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
  rootDir: '..',
  testMatch: ['<rootDir>/e2e/**/*.spec.ts'],
  preset: 'jest-expo',
  testTimeout: 120000,
  maxWorkers: 1,
  globalSetup: 'detox/runners/jest/globalSetup',
  globalTeardown: 'detox/runners/jest/globalTeardown',
  reporters: ['detox/runners/jest/reporter'],
  testEnvironment: 'detox/runners/jest/testEnvironment',
  verbose: true,
};

同じ e2e ディレクトリに、以下のように tsconfig.json を追加します。

コピーしました!

e2e/tsconfig.json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "strict": true,
    "types": ["@types/jest"]
  },
  "include": ["**/*.*"]
}

コピーしました!

shell
npx detox:build

detox でビルドすると以下のようなエラーが出たのですが、ios 以下の animatereactnative.xcworkspace というファイルを XCode で開いて、ビルドできるようにしたらエラーは出なくなりました。 animatereactnative は自分が作っていたサンプルプロジェクトの名前です。

Build settings from command line:

SDKROOT = iphonesimulator17.4

2024-03-27 23:52:21.254 xcodebuild[65338:5097306] Writing error result bundle to /var/folders/6s/vtpj9x3n243c5df1vj2n57n00000gn/T/ResultBundle_2024-27-03_23-52-0021.xcresult

xcodebuild: error: Found no destinations for the scheme 'animatereactnative' and action build.

Important: 'detox build' is a convenience shortcut for calling your own build command, as provided in the config file.

Failures in this build command are not the responsibility of Detox. You are responsible for maintaining this command.

Command failed: xcodebuild -workspace ios/animatereactnative.xcworkspace -scheme animatereactnative -configuration Release -sdk iphonesimulator -derivedDataPath ios/build

コピーしました!

shell
npm run detox:test

以下のようなエラーが出たら、

  ● Test suite failed to run

    ChildProcessError: Command failed: applesimutils --list --byType "iPhone 15"
    /bin/sh: applesimutils: command not found
     `applesimutils --list --byType "iPhone 15"` (exited with error code 127)

https://github.com/wix/AppleSimulatorUtils

コマンドをインストールします。

コピーしました!

shell
brew tap wix/brew
brew install applesimutils

テストを実行します。

テスト対象のファイルに testID を振りました。

コピーしました!

index.tsx
  return (
    <View style={styles.container} testID={'sample-test-id'}>
      <StatusBar hidden />
      <Ticker number={number} textSize={72} textStyle={{ fontWeight: '900', color: '#000' }} />
    </View>
  );

e2e/sample/sample.spec.ts は以下の通り。

コピーしました!

sample.spec.ts
import { by, device, element, expect } from 'detox';

describe('sample-test-id が開かれる', () => {
  beforeAll(async () => {
    await device.launchApp();
  });
  beforeEach(async () => {
    await device.reloadReactNative();
  });
  it('should display sign up form', async () => {
    await expect(element(by.id('sample-test-id'))).toBeVisible();
  });
});

iOSのシミュレーターが立ち上がってテストが通りました。