Xcode Test Plans(テストプラン)を使って実行対象のテストを管理する

f:id:bamboohero:20210520092655p:plain 開発プロジェクトが大きくなってくると、ユニットテスト、UIテストとテストの量がどんどん増えていきます。

特にUIテストは実行に時間がかかるので、Pull Requestが作成・更新されるたびに実行するのは現実的ではないケースもあります。

このため、Pull Requestが作成・更新されたときはユニットテストのみ、developブランチにマージされたときはユニットテストとUIテスト、リリース前の検証ではユニットテスト、UIテスト、スクリーンショットの取得など全てのテストを実行する、といったように開発の段階によって実行するテストを切り替える方針を取ることがあります。

これを実現するには2種類の方法があります。

  • Schemeを使用する
  • Test Plans(テストプラン)を使用する

本記事では上記を実現するこの2種類の方法について説明します。

実現したいこと

以下の3つのパターンを実現します。

  • ユニットテストのみを実行する
  • UIテストのみを実行する
  • ユニットテスト、UIテスト両方を実行する

Schemeを使用する

Schemeを作成する

Schemeを使って3つのパターンを実現するには、3つのSchemeを作る必要があります。

まずは、Product > Scheme > Manage Schemes...からSchemeの管理画面を開きます。プロジェクトによってはすでに複数のSchemeが作成されているかもしれませんが、ベースとしたいSchemeを選択してEdit...をクリックしてください。

f:id:bamboohero:20210426004407p:plain:w700

Duplicate SchemeをクリックしてSchemeを複製し、「UITest」という名前をつけましょう。同じ要領で「AllTests」というSchemeも作っておきます。

f:id:bamboohero:20210426004930p:plain:w700

3つのSchemeが作成された状態にします。

f:id:bamboohero:20210426005033p:plain:w700

まずはメインのScheme(ここではBambooCIApp)を編集します。

メインのSchemeではユニットテストのみを実行するようにします。

左からBuildアクションを選択し、Targetsにはメインターゲットとユニットテスト用ターゲットだけになるようにします。

f:id:bamboohero:20210426005304p:plain:w700

左からTestアクションを選択します。ユニットテスト用ターゲットのEnabledにチェックが入っていることを確認します。

f:id:bamboohero:20210426005420p:plain:w700

次に、UITest Schemeを編集します。

こちらはメインターゲットとUIテスト用ターゲットだけになるようにします。

f:id:bamboohero:20210426005534p:plain:w700

TestアクションでUIテスト用ターゲットのEnabledにチェックが入っていることを確認します。

f:id:bamboohero:20210426005613p:plain:w700

最後にAllTests Schemeを編集します。

こちらはユニットテスト用とUIテスト用の両方のターゲットが含まれるようにします。

f:id:bamboohero:20210426005711p:plain:w700

f:id:bamboohero:20210426005728p:plain:w700

テストを実行する

ユニットテストのみを実行したい場合、メインのSchemeを選択し、⌘+Uを押下します。

f:id:bamboohero:20210426005948p:plain

Test Navigatorを見ると、ユニットテストのみが実行されていることがわかります。

f:id:bamboohero:20210426010128p:plain:w300

次はUITest Schemeを選択して⌘+Uを押下します。

UIテストのみが実行されています(わかりづらいですが、ユニットテスト用ターゲット(BambooCIAppTests)のテストはグレーアウトされています)。

f:id:bamboohero:20210426010357p:plain:w300

最後にAllTests Schemeを選択して⌘+Uを押下します。

f:id:bamboohero:20210426010636p:plain:w300

Test Plans(テストプラン)を使用する

Test PlansはXcode11で追加された機能で、WWDC2019のセッションでは以下のメリットが紹介されていました。

f:id:bamboohero:20210426011425p:plain

ここで紹介するのは2つ目のメリットに当たるのかな?(ちょっと違う気もする)

Test Planを作成する

メインのScheme(ここではBambooCIApp)の編集画面を開きます。

左からTestアクションを選択し、「Convert to use Test Plans...」をクリックします。

f:id:bamboohero:20210426012251p:plain:w700

「Create Test Plan from scheme」を選択し、「Convert...」をクリックします。ここではファイル名はデフォルトのまま保存します。

f:id:bamboohero:20210426012351p:plain:w700

BambooCIApp.xctestplanというファイルが作成されました。

f:id:bamboohero:20210426012608p:plain:w700

次に、UIテストのみを実行するTest Planを作成します。Test Planは一つのSchemeに複数紐付けることができるので、Schemeを使った方法で解説したようにテストの実行単位ごとに複数のSchemeを作成する必要がないのです。

メインのSchemeの編集画面を開き、+ボタン > Create empty Test Plan...をクリックします。UITest.xctestplanという名前で保存しましょう。

f:id:bamboohero:20210426013244p:plain:w700

UITest.xctestplanを選択し、Testsタブを開きます。左下の+ボタンをクリックし、UIテスト用ターゲット(BambooCIAppUITests)を選択してAddをクリックします。

f:id:bamboohero:20210426013440p:plain:w700

同じ要領で、メインのSchemeの編集画面からAllTests.xctestplanを作成しましょう。こちらはユニットテスト用とUIテスト用両方のターゲットが含まれるようにします。

f:id:bamboohero:20210426013733p:plain:w700

テストを実行する

Test Navigatorを開くと、Schemeに紐づくTest Planが選択できるようになっています。まずはDefaultのTest Planでテストを実行してみましょう。⌘+Uを押下します。

f:id:bamboohero:20210426013934p:plain:w300

ユニットテストのみが実行されました。

f:id:bamboohero:20210426014542p:plain:w300

UITest、AllTestsを選択して⌘+Uをした結果は以下の通りです。それぞれ、UIテストのみ、ユニットテストとUIテスト両方が実行されています。

f:id:bamboohero:20210426014610p:plain:w300

f:id:bamboohero:20210426014631p:plain:w300

まとめ

実行対象のテストを管理する方法について、Schemeを使う方法とTest Planを使う方法についてご紹介しました。

チームで運用することを考えた場合、xctestplanファイルにテストに関する情報が集まっているので管理がしやすいなと思いました。

また、今回紹介したテスト対象の管理という文脈ではどちらを使う方法でもそれほど違いはないかもしれませんが、Test Planでは同じテストを言語設定を変えて複数実行できるなど、Schemeでは実現できないこともできたりするので、そのあたりは今後自分が使うことになったら記事にしようと思います。