【Unity】Unity Test Runner(Test Framework)入門 - インストールから基本的な使い方・注意点まとめ

Unity Test Runnerの基本的な使い方と使う上での注意点をまとめました。

Unity 2019.3.5
Test Framework 1.1.11

インストール

Unity2019.1以前の場合

Unity2019.1まではTest RunnerがUnityエディタに組み込まれているのでインストールする必要はありません。
その場合はこの説は飛ばして次節から読み進めてください。

Unity2019.2以降の場合

Unity2019.2からはPackage化されたため、Package Managerからインストールする必要があります。
Package ManagerからTest Frameworkと検索してインストールします。

f:id:halya_11:20200601224044p:plain
Test Frameworkをインストール

Package Managerの使い方は以下の記事にまとめていますので、必要に応じて参照してください。

light11.hatenadiary.com

Windowを開く

インストールが完了したらWindow > General > Test Runnerからウィンドウを開きます。
以下のようなウィンドウが開かれたらOKです。

f:id:halya_11:20200601225636p:plain
Test Runnerウィンドウ

テスト用のアセンブリを定義する

Unityでテストを書くには、Assembly Definition Fileによりテスト用のアセンブリを定義する必要があります。

Assembly Definition Fileを作る

Test FrameworkにはAssembly Definition Fileを作るメニューが用意されているのでこれを使います。
Assets > Create > Testing > Tests Assembly Folderを選択します。

f:id:halya_11:20200601225246p:plain
Assembly Definition Fileを作成

すると任意の名前のフォルダと、その中にフォルダと同名のAssembly Definition Fileが作成されます。

f:id:halya_11:20200601230724p:plain
フォルダとasmdefファイルがつくられる

テストスクリプトはこのフォルダ内に作っていきます。

Edit ModeとPlay Mode

さて、UnityのテストにはEdit ModeとPlay Modeが存在します。

まずEdit ModeはUnityエディタでのみ動作するテストです。
ビルドではテストできない代わりに、Unityを再生しなくてもテストを実行できます。
主にエディタ拡張のテストに使用します。

これに対してPlay Modeはビルドした環境、すなわちスマホなどの実機でもテストすることができます。
したがって再生中に使うスクリプトのテストは基本的に全てこちらで行います。
もし再生中に使うスクリプトだけどエディタの時しか通らない処理などがあればUnityPlatformアトリビュートを使ってテスト対象のプラットフォームを制限します。

docs.unity3d.com

Edit ModeとPlay Modeのアセンブリ定義

さてEdit ModeとPlay ModeはアセンブリのPlatform設定により定義されます。
Platform設定はAssembly Definition FileのInspectorから設定します。

まずEdit Modeのテストを書く場合にはPlatform設定をEditorのみにします。

f:id:halya_11:20200601231702p:plain
Edit Modeの場合

Play Modeのテストを書く場合にはPlatform設定をAny Platformにします。

f:id:halya_11:20200601231900p:plain
Play Modeの場合

またPlay Modeの場合にはAssembly Definition ReferencesからUnityEditor.TestRunnerを削除してUnityEngine.TestRunnerのみにしておきます。

f:id:halya_11:20200601235052p:plain
UnityEngine.TestRunnerのみに

テスト対象のアセンブリを設定する

次にテスト用のAssembly Definition Fileにテスト対象のアセンブリを設定します。
以下のようにAssembly Definition Referencesから対象のアセンブリを追加します。

f:id:halya_11:20200601235349p:plain
テスト対象のアセンブリ対象を追加

Test Runnerの左上のメニューからEnable playmode tests for all assembliesを選択すると、
UnityのデフォルトアセンブリであるAssembly-CSharp.dllにアクセスすることもできます。
が、これを有効にすると、ビルド時間とサイズが大きくなったり、さらにリリース時には
テストが含まれないように処理する必要もあったりとするのでやらないほうが良いかと思います。

テストを書く

簡単なテストを書く

それでは実際にテストを書いてみます。
まず、1フレームで終わるテストはTestアトリビュートを付けたメソッドとして定義します。
そしてAssert.Thatメソッドに条件式を入れてテスト処理を書きます。

using NUnit.Framework;

namespace Tests
{
    public class Example
    {
        // Testアトリビュートを付ける
        [Test]
        public void ExampleTest()
        {
            // 条件式がtrueだったら成功
            Assert.That(1 < 10);
        }
    }
}
コルーチンを使う

また、複数フレームにまたがる処理をテストするにはUnityTestアトリビュートを付けたメソッドを定義します。
戻り値をIEnumeratorとし、yield return null;でフレームを進めます。
ただしEdit Modeの場合にはEditorApplication.updateのループで処理されるので注意してください。

using NUnit.Framework;
using System.Collections;
using UnityEngine.TestTools;

namespace Tests
{
    public class Example
    {
        // UnityTestアトリビュートを付ける
        [UnityTest]
        public IEnumerator ExampleTestEnumerator()
        {
            Assert.That(1 < 10);
            // yield return nullで1フレーム進める
            yield return null;
            Assert.That(2 < 10);
            yield return null;
            Assert.That(3 < 10);
        }
    }
}
Assert.Thatの書き方

さて前節では判定にAssert.That()を使いました。
実はこれには多くのオーバーロードがあり、それらを使うことでより柔軟な条件を判定できます。
主要なものを挙げてみると以下のような感じです。

// 条件式がtrueだったら成功
Assert.That(1 < 10);
            
// 1個目の引数が2個目より小さければ成功
Assert.That(10, Is.LessThan(100));

// 1個目の引数が2個目の引数の範囲内なら成功
Assert.That(10, Is.InRange(0, 100));

// 1個めの引数の文字列が2個目の文字列で始まっていたら成功
Assert.That("Example", Does.StartWith("Ex"));

// 1個めの引数の文字列に2個目の文字列が含まれていたら成功
Assert.That("Example", Does.Contain("xamp"));

// 1個めの引数の文字列が2個目の文字列で終わっていたら成功
Assert.That("Example", Does.EndWith("ple"));

// 1個めの引数の文字列が2個目の正規表現にマッチしたら成功
Assert.That("Example", Does.Match("Ex*"));

詳しくはNUnitのドキュメントに書かれています。
このあたりは必要に応じて徐々に覚えていけばいいかと思います。

github.com

ちなみにAssert.True()とかAssert.AreEqual()とかも使えますがちょっと古い書き方(Classic Model)です。

github.com

Assertクラスについて

今回の例ではテストの判定にNUnitのAssertクラスを使いました。
実はAssertという名前のクラスはUnityEngine.Assertions.Assertにも存在します。

docs.unity3d.com

これに関しては作ったクラスやメソッドが意図したとおりに使われているかを判定するためのものであり、
NUnit及びUnity Test Frameworkとは関係がないものなので注意してください。

Unity Test FrameworkはNUnitのインテグレーションであり、下記のようなサンプルを見てもNUnitのAssertが使われていることがわかります。

docs.unity3d.com

テストを実行する

Unity上でテストを実行する

まずUnity上でテストを実行します。
テストを実行するにはTest RunnerのウィンドウからRun AllあるいはRun Selectedを選択するだけです。

f:id:halya_11:20200602001744p:plain
テストを実行する

Play Modeの場合はテスト実行時にUnityが再生状態になります。
また各項目をダブルクリックしたり右クリックメニューからも実行できます。

成功すると緑色のチェックマークが付きます。

f:id:halya_11:20200602001956p:plain
テスト成功

ビルドしてテストを実行する

次にビルドしてテストを実行します。
実行するにはPlay ModeタブでRun all in playerを選択します。

f:id:halya_11:20200602002711p:plain
ビルドして実行

StandaloneWindowsの場合には以下のようにビルドされた状態でテストが行われます。

f:id:halya_11:20200602002221p:plain
ビルドしてテスト

参考

docs.unity3d.com

github.com

qiita.com