いつも悩ましい Unity のテストですが、Play Mode でテスト内容を調整しつつ、そのままシーンを Unity Test Runner で実行 できないかなと試行錯誤した結果なんとか実現できたのでメモ。
PlayerTest ディレクトリを作成
まずUnity Test Runner をセットアップ。
メニューから Window > General > Test Runner と選択してウインドウを開きます。
PlayMode タブで Create PlayMode Test Assembly Folder をクリック。
本来ならここでテスト用のスクリプトを作成するのですが、今回の手順では作成しません。
テスト用シーンを作成
新規シーンにテストしたいオブジェクト群を構成します。
今回は Rigidbody をつけたオブジェクトを2つ用意し、1つのみ衝突判定が発生するというケースを用意しました。
スクリプトを作成
今回作成したスクリプト
MonoBehabiour 継承で作ったスクリプトのファイルに、UnityTestRunner用のクラスを追加しています。
このクラスでシーン読み込みを行います。IPrebuildSetupはまあ別になくてもよい。
MonoBehaviourでは、OnCollisionEnter でぶつかった物体の GameObject 名を判定し、Assert でテスト判定しているだけです。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.TestTools; using Assert = UnityEngine.Assertions.Assert; using UnityEngine.SceneManagement; public class TestSetup_Collision : IPrebuildSetup { [PrebuildSetup(typeof(TestSetup_Collision))] public void Setup() { Debug.Log("テスト実行前にやりたい処理"); } [UnityTest] public IEnumerator TestExec_Collision() { // 作成したテストシーンを読み込む SceneManager.LoadScene("CollisionTestScene"); yield return new WaitForSeconds(5); Assert.IsTrue(1 == 1); } } public class Test_ObstacleCollision : MonoBehaviour { void OnCollisionEnter(Collision c) { Debug.Log("Obstacle Collision"); Assert.IsTrue(c.gameObject.name == "RedSphere"); } }
このスクリプトをシーン内の Cube (下のほうにある白い箱)にアタッチしています。
PlayModeから実行する
このテスト用シーンをエディタのPlayModeで実行すると、
箱にぶつかる球によってConsoleに表示されるAssert結果が変わります。
このシーンに名前をつけて保存し、Build Setting から Scenes in Build に登録します。
ここだけはネックで、実機用にビルドしたゲームにもシーンが含まれてしまいます。
まあリリース時だけ注意すればいいのかなと思います。もしくはエディタスクリプトでなんとかするとか。
Unity Test Runner から実行する
この時点でUnityTestRunnerからも実行できるので、Run Selected ボタンから実行してみると、青い球がぶつかるケースのみテストが失敗します。
もちろん Run in Player からも実行可能
もっと良い方法あるかもしれない。特に Build Setting に追加しなくていい方法...