【Unity】Unity Test Runner(Test Framework)でコマンドラインからテストを実行する

Unity Test Runnerでコマンドラインからテストを実行する方法をまとめました。

Unity 2019.3.5
Test Framework 1.1.11
Windows環境

はじめに

本記事ではUnity Test Runnerでコマンドラインからテストを実行する方法についてまとめます。
コマンドラインの実行環境はWindowsで検証していますので、macの方は必要に応じて読み替えてください。

なお、Unity Test Runnerの基本的な使い方については以下の記事にまとめていますので必要に応じて参照してください。

light11.hatenadiary.com

コマンドラインからテストを実行する

コマンドラインからテストを実行するには-runTestsオプションを付けてUnityを実行します。

Unity.exe -runTests -projectPath PathToYourUnityProject -batchmode -testPlatform PlayMode

-projectPathにはテストを実行したいUnityプロジェクトへのパスを指定します。
またバッチモードで起動したい場合には-batchModeオプションを付けます。
-testPlatformオプションについては次節で詳しく説明します。

なおコマンドラインからテストを実行する際にはテストが終了したらエディタが自動的に終了するので-quitオプションは不要です。
むしろ-quitを付けると結果が受け取れなくなるので注意してください。

プラットフォームの指定について

さて前節の例のように-testPlatformオプションを使うと、テストの実行環境を指定できます。
まずエディタ上で実行するために以下の二つのオプション引数が用意されています。

オプション引数 意味
Edit Mode Edit ModeテストをUnityエディタ上で実行する
Play Mode Play ModeテストをUnityエディタ上で実行する

デフォルトではEdit Modeが指定されます。
またこのオプションを使うことでスマホ端末など各プラットフォーム用にビルドした環境でテストを行うこともできます。

例えばAndroid実機でテストを実行したい場合にはAndroid端末を繋いだ状態で-testPlatform Androidを指定します。
プラットフォームについてはBuildTargetに定義されているenum名を指定します。

docs.unity3d.com

テスト結果の受け取り方

さてコマンドラインからテストを実行する場合、テスト結果を何かしらの方法で受け取る必要があります。

コマンドラインの戻り値

まずコマンドラインの戻り値を受け取ります。
Windowsの場合はUnityの終了を待つために下記のようにstart /WAITする必要があります。
Unityが終了したらERRORLEVELから結果を受け取ります。

start /WAIT Unity.exe -runTests -projectPath PathToYourUnityProject -batchmode -testPlatform PlayMode
echo %ERRORLEVEL%

ERRORLEVELは実行結果に応じて以下の通りの値を返します。

ERRORLEVEL 説明
0 すべてのテストが成功
2 いくつかのテストが失敗
3 実行自体失敗(コンパイルエラーとか)
テスト結果

次にテスト結果を受け取ります。
テスト結果はデフォルトではUnityプロジェクト直下にXML形式で吐かれますが、
-testResultにファイルパスを指定することでそのパスに出力することもできます。

Unity.exe -runTests -projectPath PathToYourUnityProject -testResults PathToSomeFolder\results.xml

これにより、以下のようなテスト結果のxmlが出力されます。

<?xml version="1.0" encoding="utf-8"?>
<test-run id="2" testcasecount="3" result="Failed(Child)" total="3" passed="2" failed="1" inconclusive="0" skipped="0" asserts="0" engine-version="3.5.0.0" clr-version="4.0.30319.42000" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.0575691">
  <test-suite type="TestSuite" id="1008" name="Temp2019.3" fullname="Temp2019.3" runstate="Runnable" testcasecount="3" result="Failed" site="Child" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.057569" total="3" passed="2" failed="1" inconclusive="0" skipped="0" asserts="0">
    <properties />
    <failure>
      <message><![CDATA[One or more child tests had errors]]></message>
    </failure>
    <test-suite type="Assembly" id="1013" name="ExampleEditorTests.dll" fullname="F:/Unity/Temp2019.3/Library/ScriptAssemblies/ExampleEditorTests.dll" runstate="Runnable" testcasecount="3" result="Failed" site="Child" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.042932" total="3" passed="2" failed="1" inconclusive="0" skipped="0" asserts="0">
      <properties>
        <property name="_PID" value="1604" />
        <property name="_APPDOMAIN" value="Unity Child Domain" />
        <property name="platform" value="EditMode" />
      </properties>
      <failure>
        <message><![CDATA[One or more child tests had errors]]></message>
      </failure>
      <test-suite type="TestFixture" id="1009" name="ExampleEditorTest" fullname="ExampleEditorTest" classname="ExampleEditorTest" runstate="Runnable" testcasecount="3" result="Failed" site="Child" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.039855" total="3" passed="2" failed="1" inconclusive="0" skipped="0" asserts="0">
        <properties />
        <failure>
          <message><![CDATA[One or more child tests had errors]]></message>
        </failure>
        <test-case id="1010" name="Test01" fullname="ExampleEditorTest.Test01" methodname="Test01" classname="ExampleEditorTest" runstate="Runnable" seed="999916906" result="Passed" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.010029" asserts="0">
          <properties />
        </test-case>
        <test-case id="1011" name="Test02" fullname="ExampleEditorTest.Test02" methodname="Test02" classname="ExampleEditorTest" runstate="Runnable" seed="1339012848" result="Passed" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.000298" asserts="0">
          <properties />
        </test-case>
        <test-case id="1012" name="Test03" fullname="ExampleEditorTest.Test03" methodname="Test03" classname="ExampleEditorTest" runstate="Runnable" seed="331635698" result="Failed" start-time="2020-06-06 08:55:10Z" end-time="2020-06-06 08:55:10Z" duration="0.007437" asserts="0">
          <properties />
          <failure>
            <message><![CDATA[  Expected: True
  But was:  False
]]></message>
            <stack-trace><![CDATA[at ExampleEditorTest.Test03 () [0x00000] in F:\Unity\Temp2019.3\Assets\ExampleEditorTests\ExampleEditorTest.cs:10
]]></stack-trace>
          </failure>
        </test-case>
      </test-suite>
    </test-suite>
  </test-suite>
</test-run>
ログファイル

テスト以外のログ出力は-logFileオプションを指定することでファイル出力できます。

Unity.exe -runTests -projectPath PathToYourUnityProject -logFile F:\Unity\Temp2019.3\testLog.log

コンパイルエラーなどテストの実行自体が失敗した時などにはこのログから原因を探ることができます。

その他のオプション

フィルタリング

-testCategory-testFilterといったオプションを指定することで実行するテストをフィルタリングできます。

まず-testCategoryにはオプション引数としてカテゴリのリストをセミコロンで区切って指定します。
カテゴリはテストに対してCategoryアトリビュートで指定します。

また-testFileterはテスト名によるフィルタリングです。
こちらもセミコロンで区切ることにより複数指定できます。
正規表現を使うことも可能です。

テスト設定ファイル

-testSettingsFileオプションにTestSettings.jsonへのファイルパスを指定することでテスト設定を適用できます。
テスト設定ファイルは例えば以下のように記述することができます。

{
  "apiProfile":0,
  "scriptingBackend":2
}

設定可能な項目は以下の通りです。

項目名 説明
apiProfile .NETの互換レベル
1: .NET 2.0
2: .NET 2.0 Subset
3: .NET 4.6
5: .NET micro profile
6: .NET Standard 2.0
appleEnableAutomaticSigning iOSのAuto Signingを有効にするか
appleDeveloperTeamID Appleの開発者アカウントのチームID
architecture AndroidのCPUアーキテクチャ
0: None
1: ARMv7
2: ARM64
4: X86
4294967295: 全て
iOSManualProvisioningProfileType iOSのプロビジョニングプロファイルの種類
0: Automatic
1: Development
2: Distribution iOSManualProvisioningProfileID
scriptingBackend ScriptingBackendに何を使うか
0: Mono2x
1: IL2CPP
2: WinRT DotNET
その他のオプション

その他、使いそうなコマンドラインオプションをまとめておきます。

オプション名 説明
forgetProjectPath UnityHub起動時のプロジェクト一覧にこのプロジェクトが載らないようにする
playerHeartbeatTimeout タイムアウトとみなす時間(秒)を示す(デフォルトは10分)

参考

docs.unity3d.com

bitbucket.org

docs.unity3d.com

docs.unity3d.com