Azure PipelinesでappiumのE2Eテストを動かしてみた

先日久々にiOS Test Nightに参加させていただきました。

testnight.connpass.com

その時の発表の中にAzure Pipelinesの発表がありまして、appiumも使えるらしいとのことだったので、実際に使ってみたときのことを、まとめてみたいと思います。

やりたいこと

今回は下記の2つをAzure Pipelinesで達成したいと思います。

  • iOS simulator向けに .app ファイルのビルドを行う。
  • appiumを立ち上げ、pytestからappium python client経由でE2Eテストのスクリプト実行する。

.appファイルを書き出す

まずは .app ファイルの書き出しです。ここで必要になるTaskは3つ。1つ目がCocoaPods Task。2つ目がXcode Task。最後にArchive Files taskです。

1つ目のCocoaPods Taskについて。自前のアプリではCocoaPodsを使ってライブラリを管理しているので、このTaskが必要になります。

CocoaPods Taskの設定

CocoaPods Taskの設定はとてもシンプルです。レポジトリのrootにPodfileがあるならWorking Directoryの指定の必要もなく、Force repo updateだけが唯一の必要な設定項目です。pod install の前に pod repo update が必要であれば true 、必要なければ false とします。

azure-pipelines.yml での設定は以下のようになります。

- task: CocoaPods@0
  inputs:
    forceRepoUpdate: true

Xcode Taskの設定

続いてXcode Task。ここで実際の .app のビルドを行います。

Xcode TaskはCocoaPodsよりは多少複雑になりますが、すでに .app ファイルをビルドしたことがある人であれば、それほど難しくはないかと思います。今回使うArgumentsを一つずつ見ていきます。

  • actions: build, clean, test, analyze, and archive などのアクションを指定します。
  • sdk: 名前の通りSDKの指定です。
  • configuration: DebugReleaseの指定行います。
  • xcWorkspacePath: ビルド対象のワークスペースのPathを指定します。
  • scheme: ビルドのためのSchemeを指定します。
  • xcodeVersion: ビルドのためのXcodeのバージョンを指定します。例: 10
  • args: Azure PipelinesでArgumentsとして提供されていないようなビルドオプションなどを使いたい場合はここを使います。

今回のポイントとしては、.appファイルを書き出して、そのファイルをその後のテストのタスクで使いやすいように、指定のPathに書き出すことです。

上記を達成するために、argsのオプションから-derivedDataPathXcodeビルドオプションを使い指定のPathに.appを書き出します。

上記を踏まえたazure-pipelines.ymlは以下のようになりました。

- task: Xcode@5
  inputs:
    actions: 'build'
    sdk: 'iphonesimulator'
    configuration: 'Debug'
    xcWorkspacePath: 'VolleyScorer.xcworkspace'
    scheme: 'VolleyScorer'
    xcodeVersion: '10'
    args: '-derivedDataPath $(agent.buildDirectory)/build'

Archive Files Taskの設定

最後に.appファイルのアーカイブを行います。Archive Files taskも比較的シンプルで、書き出すファイルの指定と、書き出し先の指定のみが必要です。

- task: ArchiveFiles@2
  inputs:
    rootFolderOrFile: '$(agent.buildDirectory)/build/Build/Products/Debug-iphonesimulator/VolleyScorer.app'
    archiveFile: '$(agent.buildDirectory)/build/VolleyScorer.zip'

これで.appの準備はOK。

appiumを立ち上げpytest E2Eテストを走らせる

続いてappiumとpytestを使ったE2Eテストの実施部分です。ここでは3つのTask (Step)が必要になります。1つ目がNode.js Tool Installer taskによるNode.jsバージョンの指定。2つ目がUse Python Version taskによるPythonバージョンの指定。最後にbash taskによるテストの実施になります。

Node.jsのバージョン指定と、Pythonのバージョンの指定はバージョン名を指定するだけの非常にシンプルなものなので、説明は割愛します。

肝心のテストの実施部ですが、専用のTaskなどがないので、前述の通りBash taskを使ってひとつひとつ処理を書いていく必要があります。説明のために実際の.ymlファイルの内容を見ていきたいと思います。

- bash: |
    npm install -g appium
    appium --app $APP_PATH &
    cd tests
    pip install -r requirements.txt
    pytest test_volley.py -vv
  env:
    APP_PATH: $(agent.buildDirectory)/build/VolleyScorer.zip

上から順に見ていきましょう。

  • 1行目: -bash:はbask taskを呼び出すためのshortcut syntaxです。
  • 2行目: 残念ながらAzure Pipelines のmacOSのイメージにはappiumは入っていないので、マニュアルでインストールが必要です。なので、ここでappiumをインストールします。
  • 3行目: appiumのインストールが終わったので、appiumを立ち上げて行きます。テストスクリプト内のDesired Capabilityから.appのpathも指定可能ですが、今回はCIの中でビルドを行い、その生成物を使用するので、ここで--appコマンドラインオプションを使って.appファイルを指定しています。また、appiumを通常通り立ち上げてしまうとプロセスを取られてしますので、&をつけてバックグラウンド実行とします。
  • 4行目: testsフォルダにE2E関連のスクリプトが入っているので、こちらに移動します。
  • 5行目: 今回のappium + pytestによるE2Eで必要なライブラリはrequirements.txtに記載しているので、-rのオプションを使って必要なライブラリをインストールします。
  • 6行目: ここでpytestを呼び出し、E2Eの実行を行います。
  • 7-8行目: Bashスクリプト内から.appのパスにアクセスするために、env argumentを用いて、一旦環境変数に書き出しが必要なようです。 (追記)後で試しましたが、わざわざ環境変数に書き出さなくても直接いけました。

これで、Azure Pipelines 内でappium + pytestを使ってE2Eを走らせられるようになりました。

azure-pipelines.ymlの最終形は以下の通りです。

結果

上記のazure-pipelines.ymlを走らせた結果が以下になります。

f:id:siro_uma:20190421232231p:plain

appium serverのログとpytestの結果が混ざっているので見づらいですが、最後の方に 1 passedとあるのがわかると思います。

ということで、無事Azure Pipelines を使ってAppiumのE2Eテストを実施できました。

まとめ

初めてAzure Pipelines

を使ってみましたが、UIをポチポチとやるだけで結構簡単にパイプラインが組めますし、ドキュメントも公式のものが結構充実しているので、それほど時間がかからずに今回のパイプラインが組めました。

あと使ってみて感じたのはやっぱりローカル実施よりはE2Eの実施時間が長くなること。クローズドなGithub repoだと無料プランでは並列化できないので、実際にCICDとして使っていくかは要検討ですかね。

まだAppiumのテストしかパイプラインとしては試せていないので、実際の開発のプロセスに組み込んでいけるように、引き続き触っていきたいと思います。

参考

CocoaPods task - Azure Pipelines | Microsoft Docs

Xcode build and release task - Azure Pipelines | Microsoft Docs

Archive Files task - Azure Pipelines | Microsoft Docs

Node.js Tool Installer task - Azure Pipelines | Microsoft Docs

Use Python Version task - Azure Pipelines | Microsoft Docs

Bash task - Azure Pipelines | Microsoft Docs

speakerdeck.com