本記事は、拙著『Unity Test Framework完全攻略ガイド 統合テスト編』の付録Bから抜粋したものです。
バッチモードとは
バッチモードとは、Unityエディターをコマンドラインから起動するときに -batchmode
オプションを付けることでヘッドレス動作するモードです。
ウィンドウモード*1のUnityエディターは実行中さまざまな、人間が応答しなければならないポップアップウィンドウが表示されますが、バッチモードでは表示されません。そのため、CIでテスト実行するときなどに使用されます。
バッチモードの制限事項
本記事執筆時点で判明している、バッチモード実行時の制限事項は次のとおりです。
- スクリーンサイズは640×480
WaitForEndOfFrame
を使用できない*2InputSystem.TestFramework
を長時間(数十秒)動作させたとき、途中で操作が止まってしまうUnityEngine.InputSystem.LowLevel.InputEventTrace
を使用できない-testPlatform
オプションでスタンドアロンプレイヤーを指定したとき、バッチモードでなく常にウィンドウモードで起動する
制限事項の回避方法1
バッチモード実行中であっても、EditorWindow.GetWindow()
メソッドでUnityエディターのGameビューを開くことで前述の制限を回避できます。
ヘッドレスとは言ったがウィンドウを表示できないとは言っていない
とのこと。
次のコードは、テスト実行前にGameビューを開く ICallbacks
の実装例です。
public class OpenGameViewAtRunStarted : ICallbacks { [InitializeOnLoadMethod] private static void SetupTestCallbacks() { var api = ScriptableObject.CreateInstance<TestRunnerApi>(); api.RegisterCallbacks(new OpenGameViewAtRunStarted()); } public void RunStarted(ITestAdaptor testsToRun) { var assembly = Assembly.Load("UnityEditor.dll"); var viewClass = Application.isBatchMode ? "UnityEditor.GameView" : "UnityEditor.PlayModeView"; var gameView = assembly.GetType(viewClass); EditorWindow.GetWindow(gameView, false, null, true); } // snip }
GameView
および親クラスである PlayModeView
は可視性が internal
のため、リフレクションを使用しています。そのため、今後Unityエディターの内部実装変更によって動作しなくなる恐れがあります。
ただし、グラフィックボード・ビデオカードを搭載していないマシン、もしくは -nographics
オプションを指定しているときには、EditorWindow.GetWindow()
メソッドは機能しません。
エラーにはなりませんがウィンドウも開きません。
なお、当然ですが本当にGameビューが開きます。開発に使用しているPCで動作させたとき、フォーカスを持っていかれたり、そのままキーボード操作がテストに干渉する恐れがありますのでご注意ください。
制限事項の回避方法2
下記リポジトリで公開しているTest Helperパッケージに含まれる FocusGameView
属性も同様の実装をしています。
したがって、この属性をテストアセンブリ・クラス・メソッドいずれかに付けるだけでバッチモードの制限事項を回避できます。
また、Gameビューの解像度を指定する GameViewResolution
属性も同じ処理を含みますので、こちらでも回避できます。
まとめ
いかがでしたでしょうか?(構文)
この記事が役にたった! という方は、ぜひ『Unity Test Framework完全攻略ガイド 統合テスト編』をお買い求めください!
テストの基本から知りたい! という方は、『Unity Test Framework完全攻略ガイド 第2版』からお読みください!
*1:便宜上、通常のGUIで動作するUnityエディターを指します。公式の名称ではありません
*2:https://docs.unity3d.com/Manual/CLIBatchmodeCoroutines.html