この記事は「Unity #3 Advent Calendar 2019 - Qiita」の21日目の記事です。

Unity プロジェクトを自動ビルドするようになって、Unity Test でテストをするようになれば、次に欲しくなるのが自動テスト(たぶん)。

そして、Azure DevOps ではテストを実行するだけでなく、結果を集計してくれる便利な機能がありますので、テストの管理も楽になります。

この記事では、そんな自動テストを Azure Pipelines で行う方法を解説します。

前提条件

この記事では Azure Pipelines に Unity 入りビルドサーバーを Self hosted agent として接続する方法は解説しません。 予め、下記ドキュメントに沿って、Self hosted agent を設定してください。

Deploy a Azure Pipelines agent on Windows - Azure Pipelines | Microsoft Docs

設定方法

Unity はコマンドラインからの実行に対応しており、テストの実行を行うオプションもあります。

自動テストでもこのコマンドを使うだけなのですが、実行中のログが標準出力に出ないため、Pipeline のコンソールから状況が見れないという問題があります。

このため、ログを標準出力してくれる、こちらのツールを使います。

guitarrapc/UnityBuildRunner: Unity Build Runner for Windows Stdout

このツールのインストールを含めた、Pipeline の YAML 定義が下記になります。

trigger:
- master
- dev

pool:
  # Unity が入った Self hosted agent
  name: 'Default'

variables:
  # Unity Editor のパス
  unityEditorPath: 'C:/Program Files/Unity/Hub/Editor/2018.4.8f1/Editor/Unity.exe'
  # プロジェクトの相対パス
  unityProjectPath: './SampleProject'

steps:
# UnityBuildRunner(https://github.com/guitarrapc/UnityBuildRunner)のインストール
# 予め、サーバーにインストール済みであれば、ここのステップは不要
- powershell: 'dotnet tool update --global UnityBuildRunner'
  displayName: 'Install UnityBuildRunner'

# EditMode テストを実行する
- powershell: 'UnityBuildRunner -u ''$(unityEditorPath)'' -projectPath ''$(unityProjectPath)'' -runTests -testPlatform editmode -bachmode -silent-crashes -buildTarget WindowsStoreApps -logFile $(Build.ArtifactStagingDirectory)/Logs/EditModeTest.log -editorTestsResultFile ''$(System.DefaultWorkingDirectory)/TestResults/test-editmode-default.xml'''
  displayName: 'Run EditMode Test'
  continueOnError: true

# PlayMode テストを実行する
- powershell: 'UnityBuildRunner -u ''$(unityEditorPath)'' -projectPath ''$(unityProjectPath)'' -runTests -testPlatform playmode -bachmode -silent-crashes -buildTarget WindowsStoreApps -logFile $(Build.ArtifactStagingDirectory)/Logs/PlayModeTest.log -editorTestsResultFile ''$(System.DefaultWorkingDirectory)/TestResults/test-playmode-default.xml'''
  displayName: 'Run PlayMode Test'
  continueOnError: true

# テスト結果のxmlファイルをパブリッシュする
# Unity Test は NUnit を使用しているので、フォーマットを指定すれば、Azure DevOps で読み込み可能
- task: PublishTestResults@2
  displayName: 'Publish Test Results'
  inputs:
    testResultsFormat: NUnit
    testResultsFiles: '$(System.DefaultWorkingDirectory)/TestResults/test*.xml'
    failTaskOnFailedTests: true

# 必要に応じてビルド処理を入れる

なお、この YAML をそのまま使う場合には、variables の値を各環境、各プロジェクトに合わせて変更してください。

実行結果

実行結果は下記のようになります。

実行結果

また、テスト結果をパブリッシュしたことで、Test タブから Azure DevOps のテスト集計機能を利用できます。

テスト結果

失敗したテストのエラーメッセージや Stack trace なども Azure DevOps 上で確認できます。

テスト詳細

注意点

コマンドラインでの UnityTest 実行は、ビルドと異なり、Editor が立ち上がってプロジェクトが読み込まれます。

このため、Editor 拡張でプロジェクトを開いたときにポップアップウィンドウを出すような処理をいれた場合、ビルドサーバー側でポップアップが出てきて、詰むことがあります。

自動テストを行う場合には、InitializeOnLoadなどでユーザーの入力を必要とする処理は入れないようにするか、回避策を用意するようにしましょう。

おわりに

自動テストを Azure DevOps で構築すると、失敗したテストから Boads のバグチケットを起票したり、日々のテスト状況を集計するなど、各機能と連携して不具合管理を強力に進めていくことができます。

テストコードがまだ一部だけ、Azure DevOps を使いこなすのが難しい、など、すべてを一気に進めようとすると大変ですが、一度自動テストを組めば、少しずつ広げていくことも出来ますので、ぜひお試しいただければと思います。

では、良い CI/CD ライフを。

おまけ

記事書いている途中に GitHub の Microsoft のリポジトリに Unity ビルド(HoloLens 2用)のテンプレートを見つけました。

microsoft/Azure-DevOps-YAML-for-Unity

MS Hosted なので、ビルド速度の遅さやライセンスの用意が課題ですが、HoloLens 2 向けアプリの自動ビルドをするなら、この定義を使うのがよさそうです。