はじめに
今までUnityを使ってきてテストをしたことがなかったのですが、UniRxについて調べた時にTest Runnerがすごい便利だと気づいたので初めて触ってみました。
そこで備忘録の意味合いもかねてやり方を書き残しておきたいと思います。
環境
Unity2019.3.0f6
URP v7.1.8
下準備
デフォルトで入っていることが多いようですが、バージョンによっては入っていないことがあるようです。(私の場合は入っていました)
一応Test Frameworkが入っているかPackage Managerを確認しておくと良いでしょう。

セットアップ
まずはWindow -> General -> Test RunnerからUnity Test Runnerを開きましょう。

すると以下のようなウィンドウが開くはずです。

今回はEditModeを使っていきたいと思うので(違いを後述)、Create EditMode Test Assembly Folderをクリックします。
これをするとTestsという新しくフォルダが作成されるはずです。
ウィンドウをみてみると非アクティブだったボタンが押せるようになっているのでCreate Test Script in current folderをクリックしてください。

するとスクリプトが生成されるので、この中身にテストコードを書いていきます。

また同様なスクリプトを作成したい場合は、Create -> Testing -> C# Test Scriptからも生成できます。

EditModeとPlayMode
上部をみてみるとPlayModeとEditModeというボタンがあり、EditModeが選択されていることが分かります。
EditMode: MonoBehaviourのテストはできないが、爆速で実行できるPlayMode: MonoBehaviourのテストができる
Unity使いは全員Unity Test Runnerを使え!爆速のトライ&エラー環境だぞ! - Qiita
一番大きそうな違いを書きましたがもっと色々な違いがあるのでよければ調べてみてください。
Unity - Manual: Unity Test Runner
書き方
テストコードを書くには属性(Attribuate)をつける必要があり、2種類があります。
[Test]: 戻り値がvoidである同期的な処理[UnityTest]: 戻り値はIEnumerator,いわゆるコルーチン(EditModeではyield returnにnullのみ使用可)
またテスト特有のデバック方法として、UnityEngine.Assertions.Assertクラスを用います。
Assertions.Assert - Unity スクリプトリファレンス
メソッドをまとめるとこんな感じ。
| 名前 | 意味 |
|---|---|
| AreApproximatelyEqual | 誤差が0.00001f以下か(オーバーロードにより変更可能) |
| AreEqual | 同じ値か |
| AreNotApproximatelyEqual | 誤差が0.00001fより大きいか |
| AreNotEqual | 異なる値か |
| IsFalse | falseか |
| IsNotNull | nullではないか |
| IsNull | nullか |
| IsTrue | trueか |
実際にUniRxの動作テストを書いてみました。
using System; using System.Collections; using System.Collections.Generic; using NUnit.Framework; using UniRx; using UnityEngine; using UnityEngine.TestTools; using Assert = UnityEngine.Assertions.Assert; namespace Tests { public class Sample { [Test] public void SampleTest() { var subject = new Subject<int>(); var listNext = new List<int>(); var listError = new List<Exception>(); var listComplete = new List<Unit>(); var subscription = subject .Subscribe(x => listNext.Add(x), error => listError.Add(error), () => listComplete.Add(new Unit())); subject.OnNext(1); subject.OnNext(2); subject.OnCompleted(); subject.OnNext(3); subscription.Dispose(); Assert.AreEqual(2, listNext.Count); Assert.AreEqual(1, listNext[0]); Assert.AreEqual(2, listNext[1]); Assert.AreEqual(1, listComplete.Count); } [UnityTest] public IEnumerator SampleWithEnumeratorPasses() { var listNext = new List<Unit>(); var listComplete = new List<Unit>(); Observable.ReturnUnit() .Delay(TimeSpan.FromMilliseconds(1), Scheduler.ThreadPool) .Subscribe(x => listNext.Add(x), () => listComplete.Add(new Unit())); Assert.AreEqual(0, listNext.Count); var time = Time.time; while (true) { if (Time.time - time > 1) break; yield return null; // EditModeだとyield returnはnullのみ } Assert.AreEqual(1, listNext.Count); Assert.AreEqual(1, listComplete.Count); } } }
Run AllもしくはRun Selectedによって動作をテストします。

参照できるアセンブリファイルを追加する
例えばUniRxといったアセンブリを参照したい場合は以下のように最初に自動生成されたファイルのAssembly Definition Referencesに追加してあげる必要があります。
UniRxをusingしたいときはこんな感じ。

さいごに
とりあえず簡単なテストまでをやってみました。
簡単な動作テストなんかにも使えて便利なので、もっと早く知りたかったです。
今度はPlayModeも触れたら触ってみようと思ったり。
ではまた。