AngularJS + Cordova なアプリに Protractor + Appium を使って iOS 実機で E2E テストを実施する方法

以前、AngularJS + Cordova なアプリに Protractor + Appium を使って iOS シミュレータで E2E テストを行う方法を紹介した。

今回はその続きで、今度は iOS 実機で E2E テストを行う方法を紹介する。

前回紹介した環境設定をしてあるのが前提になる。

実際のコードはコチラ

今回紹介したパッケージとサンプルコードを利用し、AngularJS + Cordova なアプリで Appium を使った E2E テストを行うサンプルプロジェクトを作成した。以下を参考にしてほしい。

今回の例では、Appium と Protractor の起動は、Gulp タスクとして定義している。gulpfile.js はコチラ。

WebDriver Agent の設定

プロジェクトにローカルインストールした Appium の配下にある appium-xcuitest-deriver が WebDriverAgent を抱えているので、コレの設定をする。

$ cd ./node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/

$ sh ./Scripts/bootstrap.sh -d
-e Fetching dependencies

# XCode プロジェクトを開く
$ open ./WebDriverAgent.xcodeproj

XCode 上で以下のように設定を変更した。

このまま XCodeBuild をしても以下のようなメッセージが出る。

Testing failed:
Signing for "WebDriverAgentRunner" requires a development team. Select a development team in the project editor.
Code signing is required for product type 'UI Testing Bundle' in SDK 'iOS 10.3'

引き続き WebDriverAgent.xcodeproj を XCode で開き、左ペインの「TARGETS」から「WebDriverAgentRunner」を選択する。

これで Status のエラーが消える。

iOS 実機を繋いでおき、以下のコマンドでビルドする。

$ xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'id=【UDID】' test

これで実機上に WebDriver がインストールされた。コンソールは「XCTRunner[893:177871] ServerURLHere->http://192.168.2.3:8100<-ServerURLHere」という表示になったらそのまま監視状態になるので Ctrl + C で終了させる。

UDID の調べ方

  1. iOS 実機を Mac に USB 接続する。
  2. iTunes を開き、「概要」画面にある「シリアル番号」部分をクリックすると「UDID」に表示が切り替わるので、右クリック → コピー でコピーする。
  3. もしくは先程インストールした「libimobiledevice」から以下のコマンドを叩くと UDID が取得できる。
$ idevice_id --list

E2E テストを開始する

以下の手順でテストを開始する。事前に iOS 実機を USB に繋いでおくこと。

  1. iOS 実機にアプリをインストールする
  2. iOS 実機に WebDriver をインストールする
  3. Appium サーバを起動する
  4. ios-webkit-debug-proxy を起動する
  5. Protractor を実行する

1. iOS 実機にアプリをインストールする

事前に iOS 実機にアプリをインストールしておく。既にインストールできている場合は飛ばして良い。

# iOS 実機向けにビルド・インストールする
$ cordova run ios

2. iOS 実機に WebDriver をインストールする

これも既にインストールできている場合は飛ばして良い。「XCTRunner[893:177871] ServerURLHere->http://192.168.2.3:8100<-ServerURLHere」のコンソール出力で止まるので Ctrl + C で抜ける。

$ xcodebuild -project ./node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'id=【UDID】' test

3. Appium サーバを起動する

Appium サーバを起動しておく。

# Gulp タスクからローカルインストールした Appium を起動する
$ npm run gulp appium

Appium をグローバルインストールしておき、$ appium で起動した場合は途中で WebDriver Agent のビルドが失敗して上手くいかなかった。Appium 自身の配下にある WebDriver Agent を使用しようとして、未設定のためにビルドが失敗するものと思われる。

コンフィグ設定は以下のように記述して動作したが、デフォルト設定とほとんど同じため、コンフィグ設定を指定せずとも動作するものと思われる。

/* nodeConfig.json */

{
  "configuration": {
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
    "url": "http://127.0.0.1:4723/wd/hub",
    "host": "127.0.0.1",
    "port": 4723,
    "maxSession": 1
  }
}

4. ios-webkit-debug-proxy を起動する

Appium サーバより後に起動する。コンソールには何やらバイナリが出力される。

$ ios_webkit_debug_proxy -c 【UDID】:27753 -d

5. Protractor を実行する

iOS 実機のロックは解除しておくこと。

$ npm run gulp e2e

protractor.conf.js の設定内容を検証した結果は以下のとおり。

消したらダメだった設定項目

消して良い設定項目

書かなくても影響ないが、入れておくと良いと思われる設定項目

というわけで、以下の設定が最小限の設定内容となった。

exports.config = {
  // Appium サーバの URL を指定する
  seleniumAddress: 'http://127.0.0.1:4723/wd/hub',
  
  // Capabilities to be passed to the webdriver instance.
  capabilities: {
    // 必須設定
    browserName: '',
    autoWebview: true,
    
    // テスト対象のアプリ情報
    app : './platforms/ios/build/device/【アプリ名】.app',
    bundleId: '【アプリ識別子】',
    
    // テストを実施する iOS 実機情報
    deviceName : '【iOS 実機名】',
    udid : '【UDID】',
    platformName : 'iOS',
    platformVersion: '10.3',
    
    // その他設定
    // iOS シミュレータの場合にアプリのディレクトリを削除してアプリを初期化する場合は true
    fullReset : false,
    // WebView のタイムアウト
    autoWebviewTimeout: 20000,
    // 自己証明書の確認アラートが表示されるとき自動で許可する場合は true
    autoAcceptAlerts : true
  },

// 以下略

というワケで手順まとめ

  1. iOS 実機を USB 接続する。
  2. iOS 実機にテスト対象アプリが入っていなければインストールする。
    • $ npm run run:ios
    • ./platforms/ios/build/device/【アプリ名】.app が生成されていることを確認しておくと良い。
  3. WebDriverAgent とその配下にある WebDriverAgentRunner の識別子 (Bundle Identifier) を端末ごとにユニークなモノに変更する。
    • $ open ./node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj
    • 左ペイン TARGETS : WebDriverAgentLib → General タブ → Bundle Identifier
    • 左ペイン TARGETS : WebDriverAgentRunner → Build Settings タブ → Product Bundle Identifier
    • Appium が起動する際に再ビルドするようなので、以下の手順 4. を飛ばす場合もやっておいた方が良い。
  4. iOS 実機に WebDriver が入っていなければインストールする。
    • $ xcodebuild -project ./node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'id=【UDID】' test
    • ServerURLHere とコンソールに出力されたら Ctrl + C で終了する。
  5. 1つ目のターミナルで Appium サーバを起動する。
    • $ npm run gulp appium
  6. 2つ目のターミナルで ios-webkit-debug-proxy を起動する。
    • $ ios_webkit_debug_proxy -c 【UDID】 -d
  7. protractor.conf.js に実機の UDID を記載する。
    • appbundleId もついでに確認しておく (iOS シミュレータの場合と設定が異なる部分なので)。
  8. 3つ目のターミナルで Protractor を実行する。
    • $ npm run gulp e2e

テスト中について

テスト中は Safari インスペクタでの参照は不可。

テストを終了する

テストを終了する際は以下の順に終了処理を行う。

  1. npm run gulp e2e でのテストが完了するまで待つか、Ctrl + C で終了させる。
  2. ios-webkit-debug-proxy を起動しているターミナルを Ctrl + C で終了させる。
  3. npm run gulp appium を起動しているターミナルを Ctrl + C で終了させる。

以上。