woshidan's blog

あいとゆうきとITと、とっておきの話。

xcodebuild testのテスト対象のデバイスやテストケースをappiumぽく簡単に指定できるラッパースクリプトを書いてみた

この記事はiOS2 Advent Calendar 2017の3日目の記事です。

xcodebuild testのテスト対象のデバイスやテストケースをややappiumみたいに簡単に指定できるラッパースクリプトを書いてみました。 なお、CocoaPodsでライブラリ管理をしているプロジェクトを対象としています。CocoaPodsをご利用でない場合は、適宜 -workspace-project オプションに読み替えていただけると幸いです。

スクリプト

スクリプト本体 xcode-wrapper.sh

#!/bin/bash

# configuration for project, written here
WORKSPACE="ExmapleApp.xcworkspace"
APP_SCHEME="ExmapleApp"
TEST_SCHEME="ExmapleAppTests"
BUILD_CONFIG="Debug"

# configuration for test target device written in caps.json
TARGET_LABEL=$(jq .target < ./caps.json)
DEVICE_NAME=$(jq .[$TARGET_LABEL]."deviceName" < ./caps.json | tr -d '"')
PLATFORM_VERSION=$(jq .[$TARGET_LABEL]."platformVersion" < ./caps.json | tr -d '"')
DEVICE_ID=$(jq .[$TARGET_LABEL]."udid" < ./caps.json | tr -d '"')
DEVICE_TYPE=$(jq .[$TARGET_LABEL]."type" < ./caps.json | tr -d '"')

build() {
  if [ "$DEVICE_TYPE" = "simulator" ]
  then
    # refs: https://qiita.com/roothybrid7/items/19f0aeeee98573dab2a6
    xcodebuild \
      -sdk iphonesimulator \
      -destination "platform=iOS Simulator,name=${DEVICE_NAME},OS=${PLATFORM_VERSION}" \
      -configuration "$BUILD_CONFIG" \
      -workspace "$WORKSPACE" -scheme "$APP_SCHEME" \
      build
  else
    xcodebuild \
      -sdk iphoneos \
      -destination "platform=iOS,id=${DEVICE_ID}" \
      -configuration "$BUILD_CONFIG" \
      -workspace "$WORKSPACE" -scheme "$APP_SCHEME" \
      build
  fi
}

test() {
  if [ "$DEVICE_TYPE" = "simulator" ]
  then
    xcodebuild -workspace $WORKSPACE \
      -scheme "$TEST_SCHEME" \
      -sdk iphonesimulator \
      "$TEST_CASE_OPTION" \
      -destination "platform=iOS Simulator,name=${DEVICE_NAME},OS=${PLATFORM_VERSION}" test
  else
    xcodebuild -workspace $WORKSPACE \
      -scheme "$TEST_SCHEME" \
      -sdk iphoneos \
      "$TEST_CASE_OPTION" \
      -destination "platform=iOS,id=${DEVICE_ID}" test
  fi
}

if [ $1 == "build" ]; then
    build
fi

if [ $1 == "test" ]; then
    i=1
    for OPT in "$@"
    do
        if [ $OPT = "-test" ]; then
            TEST_CASE_OPTION="-only-testing:${TEST_SCHEME}/${@:$(expr $i + 2):1}"
            test
            exit 0
        fi
        i=$(expr $i + 1)
    done
    test
fi

設定ファイル caps.json

"target" の部分を変更してテストを実行するデバイスを切り替えます。

{
  "target": "iPhone5", // テストで使うデバイスの指定
  "iPhone5": {
    "type": "simulator", // シミュレータ
    "deviceName": "iPhone 5",
    "platformVersion": "9.3",
    "udid": "" // シミュレータの指定では使わない
  },
  "iPhone6": {
    "type": "simulator", // シミュレータ
    "deviceName": "iPhone 6",
    "platformVersion": "10.0",
    "udid": "" // シミュレータの指定では使わない
  },
  "iPhone7": {
    "type": "simulator", // シミュレータ
    "deviceName": "iPhone 7",
    "platformVersion": "11.1",
    "udid": "" // シミュレータの指定では使わない
  },
   "iPad": {
    "type": "iphoneos", // 実機
    "deviceName": "woshidanのiPad", "" // 実機の指定では使わない
    "platformVersion": "10.3",
    "udid": "DUMMY_ID"
  }
}

使用例

# 全てのテストを実行する
$ ./xcode-wrapper.sh test

# ExmapleTestクラスにおいたテストをすべて実行する
$ ./xcode-wrapper.sh test -test ExmapleTest

# ExmapleTestクラスにおいたテストメソッドtestAを実行する
$ ./xcode-wrapper.sh test -test ExmapleTest/testA

# アプリをビルドする
$ ./xcode-wrapper.sh build

補足

実行されるテストを指定したい

CLIから見守るだけとはいえ、毎回全てのテストを実行するのは時間がかかります。 xcodebuild test サブコマンドは only-testing オプションを用いることで実行するテストを指定することができます。

https://stackoverflow.com/questions/39427263/how-to-use-xcodebuild-with-only-testing-and-skip-testing-flag

上記スクリプトでは、-test オプションを指定することで only-testing オプションで指定する文字列を与えることができます。スクリプト自体は -test オプションなしでも利用可能で、その場合は全てのテストを実行します。

利用できるデバイスの名前やID, OSバージョンの組み合わせについて

caps.json に書くシミュレータや実機デバイスの名前、OSバージョン、IDなどがわからない場合はXCodeAdd Simulators ... の画面か $ instruments -s devices コマンドより確認できます。

XCodeのデバイス管理画面から

f:id:woshidan:20171202232044p:plain

ターミナルから

$ instruments -s devices
...
iPhone SE (10.0) [7DB19BC4-5A56-4D40-93BD-90F551713043] (Simulator)
iPhone SE (10.3.1) [10FE1E72-D129-4593-A18B-AE85F4D9DC78] (Simulator)
iPhone SE (11.1) [C511B853-09C3-4599-A88F-737296F02DED] (Simulator)
iPhone X (11.1) [95022FBF-DDDB-46A8-8978-0129C0A6142D] (Simulator)
...

もっと色々書こうかと思ったのですが力尽きたので現場からは以上です。