はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】Unity Test Runnerを初めて触ってみる(EditModeのみ)

はじめに

今までUnityを使ってきてテストをしたことがなかったのですが、UniRxについて調べた時にTest Runnerがすごい便利だと気づいたので初めて触ってみました。

そこで備忘録の意味合いもかねてやり方を書き残しておきたいと思います。

環境

Unity2019.3.0f6
URP v7.1.8

下準備

デフォルトで入っていることが多いようですが、バージョンによっては入っていないことがあるようです。(私の場合は入っていました)

一応Test Frameworkが入っているかPackage Managerを確認しておくと良いでしょう。

f:id:hanaaaaaachiru:20200508154536p:plain

セットアップ

まずはWindow -> General -> Test RunnerからUnity Test Runnerを開きましょう。

f:id:hanaaaaaachiru:20200508161341p:plain

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

f:id:hanaaaaaachiru:20200508161609p:plain

今回はEditModeを使っていきたいと思うので(違いを後述)、Create EditMode Test Assembly Folderをクリックします。

これをするとTestsという新しくフォルダが作成されるはずです。

ウィンドウをみてみると非アクティブだったボタンが押せるようになっているのでCreate Test Script in current folderをクリックしてください。

f:id:hanaaaaaachiru:20200508165722p:plain

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

f:id:hanaaaaaachiru:20200508170336p:plain

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

f:id:hanaaaaaachiru:20200508170221p:plain

EditModeとPlayMode

上部をみてみるとPlayModeEditModeというボタンがあり、EditModeが選択されていることが分かります。

  • EditMode : MonoBehaviourのテストはできないが、爆速で実行できる
  • PlayMode : MonoBehaviourのテストができる

Unity使いは全員Unity Test Runnerを使え!爆速のトライ&エラー環境だぞ! - Qiita

一番大きそうな違いを書きましたがもっと色々な違いがあるのでよければ調べてみてください。
Unity - Manual: Unity Test Runner

書き方

テストコードを書くには属性(Attribuate)をつける必要があり、2種類があります。

  • [Test] : 戻り値がvoidである同期的な処理
  • [UnityTest] : 戻り値はIEnumerator,いわゆるコルーチン(EditModeではyield returnnullのみ使用可)

またテスト特有のデバック方法として、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によって動作をテストします。

f:id:hanaaaaaachiru:20200508184528p:plain

参照できるアセンブリファイルを追加する

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

UniRxusingしたいときはこんな感じ。

f:id:hanaaaaaachiru:20200508173858p:plain

さいごに

とりあえず簡単なテストまでをやってみました。

簡単な動作テストなんかにも使えて便利なので、もっと早く知りたかったです。

今度はPlayModeも触れたら触ってみようと思ったり。

ではまた。