GithubActionsでiOSのUnitTestをしてみた
GithubActionsでiOSのUnitTestを自動で走らせるCIを作成してみました。
思ったよりも苦戦したので苦戦した箇所も合わせて記述しておきます。
GithubActionsでiOSのUniTestを動かす
GithubActionsでCIを動かすためのymlを作成します。
.git/workflow/UnitTest.yml を以下のコードで作成しましょう。
name: UnitTest
run-name: ${{ inputs.title }} - @${{ github.ref_name }}
on:
workflow_dispatch:
inputs:
title:
required: true
type: string
default: "UnitTest"
description: "Title"
jobs:
unit_test:
runs-on: macos-last
timeout-minutes: 25
steps:
# checkout
- name: checkout
uses: actions/checkout@v4
# sw_vers
- name: sw_vers
run: sw_vers
# list devices
- name: list devices
run: xcrun simctl list devices
# unit test
- name: unit test
run: xcodebuild -project MyProject.xcodeproj -scheme MyProject -resultBundlePath TestResults -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14,OS=16.2' test
# xcresult
- name: xcresult
uses: kishikawakatsumi/xcresulttool@v1
with:
path: TestResults.xcresult
if: success() || failure()
設置ができたら
GithubのAction > UnitTest > Run workflow▼
から実行可能です
xcodebuild: error: Unable to find a destination matching the provided destination specifierというエラーがでる
xcodebuild: error: Unable to find a destination matching the provided destination specifier:
{ platform:iOS Simulator, OS:16.5, name:iPhone 14 }
実行する上記のようなエラーが出る場合があります。
指定したシュミレーターの端末とOSが見つからないよというエラーらしいです。
そこで使えるiOSと端末を調べる必要がでてきます。
そんなときは
$ xcrun simctl list devices
このコマンドでシュミレーターの一覧を表示することができます。
もちろんGithubActionsでも可能です。
今回は事前に設定しておきました。
このように出るので使用できる端末とOSを確認したらテストの部分を変更しましょう。
今回はiPhone 15 iOS17.2にします。
修正前
run: xcodebuild -project {プロジェクト名}.xcodeproj -scheme {スキーム名} -resultBundlePath TestResults -sdk iphonesimulator -destination 'platform=iOS Simulator,name={端末},OS={OS}' test
修正後
run: xcodebuild -project MyProject.xcodeproj -scheme MyProject -resultBundlePath TestResults -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' test
しかしこれでもエラーが治らない時があります。
色々調べたところ runs-on: macos-latest が実は最新のmacosをとってこない場合があることがわかりました。
そこでmacosに関してはバージョンを指定することで回避します。
修正前
runs-on: macos-latest
修正後
runs-on: macos-14
これでOKですが念の為macのバージョンを表示して確認することにしましょう。
$ sw_vers
macOSのバージョン確認方法です。
今回はすでにymlに記述しています。
% sw_vers
ProductName: macOS
ProductVersion: 14.4
BuildVersion: 23E214
このようにバージョンが表示されるので確認しましょう。
私の環境ではmacos-14、iPhone 15、iOS 17.2でうまくいきました。
Resource not accessible by integrationというエラー
Resource not accessible by integration
次にこのようなエラーが出た場合ですが、これはテスト結果をみやすくするライブラリ「kishikawakatsumi/xcresulttool@v1」に関するエラーです。
権限の問題なのでGithubの権限を変更しましょう。
GithubのSetting > Action > General > Workflow permissions > Read and write permissions
に変更する必要があります
Cannot test target “TestProjectUITests” on “My Mac”: UI tests are not supported on My Macというエラー
Cannot test target “TestProjectUITests” on “My Mac”: UI tests are not supported on My Mac
xcodebuildのtestを走らせるとUnit TestとUI Testの両方が走りUI Testの方で失敗していまいます。
私の場合はUI Testは不要だったのでUnit Testだけに絞ることで回避しました。
UI Testを含めるとテストが数十分以上かかるので不要な場合はUnit Testだけに絞る方がすぐに終わるのでおすすめです。
Unit Testだけにする場合は以下のようにコードを修正する必要があります。
修正前
run: xcodebuild -project MyProject.xcodeproj -scheme MyProject -resultBundlePath TestResults -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' test
修正後
xcodebuild -project TestProject.xcodeproj -scheme TestProject -resultBundlePath TestResults -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' '-only-testing:MyProjectTests' test
'-only-testing:MyProjectTests'を追加し、MyProjectTestsフォルダ以下にあるテストのみを実行するように修正しました。
'-only-testing:MyProjectTests/AAATests'のようにさらに絞ったり、特定のテストだけを実行することも可能のようです。
覚えておくと便利かもしれません。
最終コード
name: UnitTest
run-name: ${{ inputs.title }} - @${{ github.ref_name }}
on:
workflow_dispatch:
inputs:
title:
required: true
type: string
default: "UnitTest"
description: "Title"
jobs:
unit_test:
runs-on: macos-14
timeout-minutes: 25
steps:
# checkout
- name: checkout
uses: actions/checkout@v4
# sw_vers
- name: sw_vers
run: sw_vers
# list devices
- name: list devices
run: xcrun simctl list devices
# unit test
- name: unit test
run: xcodebuild -project TestProject.xcodeproj -scheme TestProject -resultBundlePath TestResults -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.2' '-only-testing:TestProjectTests' test
# xcresult
- name: xcresult
uses: kishikawakatsumi/xcresulttool@v1
with:
path: TestResults.xcresult
if: success() || failure()