はじめに
今まで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
も触れたら触ってみようと思ったり。
ではまた。