2
2

More than 3 years have passed since last update.

iOSでFlankを使ってFirebase Test LabでUITest

Last updated at Posted at 2020-03-06

テストの分割などが可能なツール、FlankをiOSのUITestで導入してみます。

公式githubのREADME.mdももちろん見てください。
https://github.com/Flank/flank

Bitriseでの利用は別記事で触れています。

環境

  • macOS Mojave 10.14.6(18G103)
  • java version "1.8.0_241"
  • Flank v8.1.0
  • gcloud Google Cloud SDK 276.0.0, bq 2.0.52, core 2020.01.10, gsutil 4.47

環境の準備

私はおもむろにContributingの項目の設定をはじめてしまいました。
使うだけの人はiOS exampleの項目からはじめましょう。

java

ここではjdk-8u241-macosx-x64.dmgを使いインストールしました。
https://www.oracle.com/java/technologies/javase-jdk8-downloads.html

$ java -version
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)

java8にこだわらなくても良いと思いますがjava13だと動きませんでした。

gcloud CLI

インストールがまだの方はこちらから
https://cloud.google.com/sdk/gcloud?hl=ja

$ gcloud --version
Google Cloud SDK 276.0.0
bq 2.0.52
core 2020.01.10
gsutil 4.47

Google App Credentials

Google Credentials JSONを用意します。
ない方は以下から作成できます。p12とjsonが選べる場合はjson形式でokです。
https://console.cloud.google.com/apis/credentials/serviceaccountkey

storageへ書き込む権限が必要です。

ここでは以下のファイルがダウンロードされました。
kanari3-develop-ios-55a55aaa55aa.json

環境変数にexportします。

# ex: (例)
export GOOGLE_APPLICATION_CREDENTIALS='保存したパス/kanari3-develop-ios-55a55aaa55aa.json'

毎回流すのが面倒な方は.bash_profileなどに書いておきましょう。

iOS側

UITestが動くアプリを準備してください。

確認しておく項目は以下です。

  • UITest用のScheme名

xcode-scheme.png

ここではUITestSampleUITestsとなっています。

How-to-Use Flank

流れは以下のような感じです。

  • UITest用アプリのBuild
  • UITest用アプリのArchive
  • Flankのclone
  • ios.ymlを編集しておく
  • Flankをビルド
  • ビルドしたFlankのjarを実行

UITest用アプリのBuild

※ XCUITestでは、アプリ本体と別に、テスト用アプリをビルドして使います。

  • XcodeのIDEではなくコマンドでビルドします。
  • テストしたいアプリのルートで以下を実行してビルドします。
  • ここではDerivedDataをプロジェクト以下に置きました。(commitしないようにしてください)
  • MyProject、MyUITestsSchemeは適時読み替えてください。
xcodebuild -workspace MyProject.xcworkspace \
  -scheme MyUITestsScheme \
  -derivedDataPath MyDeriverdData \
  -sdk iphoneos build-for-testing

UITest用アプリのArchive

以下のコマンドでzip化します。

cd MyDeriverdData/Build/Products ; \
zip -r MyTestApp.zip Debug-iphoneos MyUITestsScheme_iphoneos*-arm64e.xctestrun

MyUITestsScheme_iphoneos*-arm64e.xctestrunの箇所はファイル名なので補完を効かせて入力しましょう

Flankのclone

cloneして中に移動します。

git clone git@github.com:Flank/flank.git && cd flank

ios.ymlを編集しておく

./test_runner/flank.ios.yml

まずは、最低限の設定をしてFlankでのテストを通しましょう。
Line番号はFlankのversionにより変わると思うので大体です。
ベースは書かれているのでコメントアウトを外して追記します。

  • L:41 test:

アーカイブのパスです。

相対パスや絶対パスで入力します。
実運用ではflank.ios.ymlをアプリプロジェクトに内包すればパスは書きやすくなるかも知れませんね。

# L:41 ex:
test: /works/UITestSample/MyTests/Build/Products/MyTests.zip
  • L:47 xctestrun-file:

xctestrunファイルのパスです。

# L:47 ex:
xctestrun-file: /works/UITestSample/MyTests/Build/Products/UITestSampleUITests_iphoneos12.3-arm64e.xctestrun

DeploymentTargetにより12.3の箇所が変わるので実際のファイル名を確認してください。

Flankをビルド

cd test_runner/
./gradlew clean build fatJar

成功したときのログは以下

BUILD SUCCESSFUL in 1m 17s
16 actionable tasks: 16 executed

ビルドしたFlankのjarを実行

Flankを使ってFirebase Test LabでUITestを実行します。

java -jar ./build/libs/flank-*.jar firebase test ios run

flank-*の箇所は私の環境ではflank-SNAPSHOT.jarでした。

実行時のログは以下

$ java -jar ./build/libs/flank-*.jar firebase test ios run
IosArgs
    gcloud:
      results-bucket: test-lab-4d0240uptt2s2-j0tb4zpdrhnc5
      results-dir: null
      record-video: false
      timeout: 15m
      async: false
      results-history-name: null
      # iOS gcloud
      test: /work/UITestSample/MyTests/Build/Products/MyTests.zip
      xctestrun-file: /work/UITestSample/MyTests/Build/Products/UITestSampleUITests_iphoneos13.2-arm64e.xctestrun
      xcode-version: null
      device:
        - model: iphone8
          version: 12.0
          locale: en
          orientation: portrait
      num-flaky-test-attempts: 0

    flank:
      max-test-shards: 1
      shard-time: -1
      num-test-runs: 1
      smart-flank-gcs-path:
      smart-flank-disable-upload: false
      test-targets-always-run:

      files-to-download:

      # iOS flank
      test-targets:

      disable-sharding: false
      project: kanari3-develop-ios
      local-result-dir: results
RunTests
  Uploading MyTests.zip .
Found xctest: /work/UITestSample/MyTests/Build/Products/Debug-iphoneos/UITestSampleUITests-Runner.app/PlugIns/UITestSampleUITests.xctest
isMacOS = true (mac os x)
nm -U "/work/UITestSample/MyTests/Build/Products/Debug-iphoneos/UITestSampleUITests-Runner.app/PlugIns/UITestSampleUITests.xctest/UITestSampleUITests"
nm -gU "/work/UITestSample/MyTests/Build/Products/Debug-iphoneos/UITestSampleUITests-Runner.app/PlugIns/UITestSampleUITests.xctest/UITestSampleUITests" | xargs -s 262144 xcrun swift-demangle

  Smart Flank cache hit: 0% (0 / 1)
  Shard times: 120s

  1 test / 1 shard

  Uploading UITestSampleUITests_iphoneos13.2-arm64e.xctestrun .
  1 matrix ids created in 0m 5s
  https://console.developers.google.com/storage/browser/test-lab-4d0240uptt2s2-j0tb4zpdrhnc5/2020-03-06_01-58-13.697000_pdKG/

PollMatrices
  0m  1s matrix-71ucqbcx81avk iphone8-12.0 VALIDATING
  0m 13s matrix-71ucqbcx81avk iphone8-12.0 PENDING
  0m 25s matrix-71ucqbcx81avk iphone8-12.0 Starting attempt 1.
  0m 25s matrix-71ucqbcx81avk iphone8-12.0 Checking Internet connection...
  0m 25s matrix-71ucqbcx81avk iphone8-12.0 RUNNING
  0m 56s matrix-71ucqbcx81avk iphone8-12.0 Internet connection stable!
  1m  9s matrix-71ucqbcx81avk iphone8-12.0 Started device logs task
  2m 27s matrix-71ucqbcx81avk iphone8-12.0 Stopped device logs task
  2m 36s matrix-71ucqbcx81avk iphone8-12.0 Done. Test time = 60 (secs)
  2m 36s matrix-71ucqbcx81avk iphone8-12.0 Starting results processing. Attempt: 1
  2m 36s matrix-71ucqbcx81avk iphone8-12.0 Completed results processing. Time taken = 4 (secs)
  2m 36s matrix-71ucqbcx81avk iphone8-12.0 FINISHED
  2m 36s matrix-71ucqbcx81avk FINISHED

FetchArtifacts
  .
  Updating matrix file

CostReport
  Physical devices
    $0.08 for 1m

MatrixResultsReport
  1 / 1 (100.00%)

ログ解説

ここでは成功率は1/1で100% PASSとなっていますが、Matrix単位なので、UITestが複数ケースあっても1/1となります。

GCPのストレージにMyTests.zipがアップロードされているのが確認できると思います。

金額は$0.08課金されています。

実行デバイスはFirebase Test Labのdefaultデバイスが自動的に選択されます。
確認したい方は以下

$ gcloud firebase test ios models list
┌─────────────┬───────────────────────┬─────────────────────┬──────────────────────────────────┐
│   MODEL_ID  │          NAME         │    OS_VERSION_IDS   │               TAGS               │
├─────────────┼───────────────────────┼─────────────────────┼──────────────────────────────────┤
│ ipad5       │ iPad (5th generation) │ 11.2,12.0           │ deprecated=11.2                  │
│ ipadmini4   │ iPad mini 4           │ 11.2,12.0           │ deprecated=11.2                  │
│ ipadpro_105 │ iPad Pro (10.5-inch)  │ 11.2                │ deprecated=11.2                  │
│ iphone11    │ iPhone 11             │ 13.3                │                                  │
│ iphone11pro │ iPhone 11 Pro         │ 13.3                │                                  │
│ iphone6     │ iPhone 6              │ 11.4,12.2           │ deprecated=11.4                  │
│ iphone6s    │ iPhone 6s             │ 10.3,11.2,11.4,12.0 │ deprecated=10.3, deprecated=11.2 │
│ iphone7     │ iPhone 7              │ 11.2,11.4,12.0,12.3 │ deprecated=11.2                  │
│ iphone7plus │ iPhone 7 Plus         │ 11.2,11.4,12.0      │ deprecated=11.2                  │
│ iphone8     │ iPhone 8              │ 11.2,11.4,12.0      │ deprecated=11.2, default         │
│ iphone8plus │ iPhone 8 Plus         │ 11.2,11.4,12.0,12.3 │ deprecated=11.2                  │
│ iphonese    │ iPhone SE             │ 11.2,11.4,12.0,12.3 │ deprecated=11.2                  │
│ iphonex     │ iPhone X              │ 11.2,11.4,12.0,12.3 │ deprecated=11.2                  │
│ iphonexr    │ iPhone XR             │ 13.2                │                                  │
│ iphonexs    │ iPhone XS             │ 12.0,12.1,12.3      │                                  │
│ iphonexsmax │ iPhone XS Max         │ 12.0,12.1,12.3      │                                  │
└─────────────┴───────────────────────┴─────────────────────┴──────────────────────────────────┘

ステップアップ

Firebase Test LabのUITest録画機能を使ってみましょう

設定

ios.ymlのL:18のrecord-video:をtrueに設定します。

record-video: true

実行結果

ログのhttps://console.developers.google.com/storage/browser/の箇所にアップロードされたファイルが格納されています。

動画ファイルはここでは以下に保存されていました。
shard_0/iphone8-12.0-en-portrait/video.mp4

テスト失敗時

ログは以下のようになります。

MatrixResultsReport
  0 / 1 (0.00%)
  1 matrices failed

HtmlErrorReport written to /work/flank/test_runner/results/flank-uitest/HtmlErrorReport.html
Error: Matrix failed: matrix-71ucqbcx81avk FINISHED failure  https://console.firebase.google.com/project/kanari3-develop-ios/testlab/histories/bh.49d8d135811054f7/matrices/8560953674081399197/executions/bs.9f408b536f2a9f54

テストレポートのURLが表示されていて親切ですね。

リンクに飛ぶと以下のような画面になります。

ftl1.png

動画タブでは動画が再生できます。

ftl3.png

textExample()のテストケースを選択すると個別のエラーログが見れます。

ftl2.png

TestCaseにXCFail("わざと失敗させました")を挿入してみました。

管理

GCPのバケットがどんどん溜まっていくのでディレクトリを設定しましょう。
必要なファイルが埋もれるとまとめて消すときに事故のもとです。

# L:12 ex
results-dir: flank-uitest

Cloud Storageの無料枠 (5GB) も意識しましょう。

トラブルシューティング

GOOGLE_APPLICATION_CREDENTIALSが読めない

~/ に置くとFlankから読めないことがあるようです。

おわり

随時追記します。
シャードを分けた並列テストについては別記事を書く予定です!

次はBitriseからFlankを使う方法について触れます。
BitriseでもFlankを使ってFirebase Test LabでUITestしたい

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2