【令和最新版】実はUnityの単体テストは割と手軽に書ける【2024年版】

# Tests Assembly Folder は別に必須ではない

そんなものいらないです、実は。

## ゲームのコードをわざわざAssembly DefinationでAssembly-CSharp以外にするのつらスンギと思ってませんか？

自分も思ってました。そうしないとUnity Test Frameworkを使えないと思ってましたから…

なにせこうやって

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21596/37a72ccd-7ea6-50dd-fab0-31e3e537ce9d.png)

テストアセンブリフォルダを作ってないとテストスクリプトのテンプレ生成もさせてくれませんからね。
でもUnityのUIに言われるがままテストアセンブリフォルダを作ってテストコードを配置して、とやると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21596/4921d1bd-2313-2140-20cc-395293992e7c.png)

肝心のテストをしたい対象である自分のコードを参照できません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21596/6bfa16ae-df50-e544-01f2-6977398295c5.png)

これを解決するためにはAssembly Definationを新規制作してゲームのコードたちをそっちのアセンブリーに所属させテストアセンブリからそれを参照するようにすればいい、と言われるんですが、それをやってしまうといままで明示指定しなくても通っていたPackageManager経由で導入したライブラリたちへの参照が軒並みなくなってしまい、全部手動で設定しなければならなくなります。不便すぎる…

https://qiita.com/nir_takemi/items/bca2094431afe882394f

## Assembly-CSharpも対象する設定ができるTestRunnerの「右上のメニュー」はどこ行った？

https://qiita.com/karinharp/items/e8b7843a01a850b5c657

この面倒を回避できそうな、上記記事で言及されている「TestRunner右上のメニュー」、Unity6、というかこの記事制作時点の最新バージョンである Unity Test Framework 1.4.5では無くなっています。

テストコードを製品版に残してしまう可能性もあるからUnityはこの手段を封じてきたのか…？

## 現在はAssembly-CSharp/Assembly-CSharp-Editorも対象とする設定がデフォルト（というか変更できなさげ）

なんのことはない、今はメニューでオンにしなくてもAssembly-CSharp/Assembly-CSharp-Editorをテストコード検索の対象に、**デフォルトでなっています**。

# まとめると、単に[Test]がついてるメソッドのあるクラスを書けばいいだけ

つまり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21596/37a72ccd-7ea6-50dd-fab0-31e3e537ce9d.png)

こうなってるせいで騙されますが、

``` NewEditModeTestScript.cs
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;

public class NewEditModeTestScript
{
    // A Test behaves as an ordinary method
    [Test]
    public void NewEditModeTestScriptSimplePasses()
    {
        // Use the Assert class to test conditions
    }

    // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
    // `yield return null;` to skip a frame.
    [UnityTest]
    public IEnumerator NewEditModeTestScriptWithEnumeratorPasses()
    {
        // Use the Assert class to test conditions.
        // Use yield to skip a frame.
        yield return null;
    }
}
```

``` NewRunModeTestScript.cs
#if UNITY_EDITOR || UNITY_INCLUDE_TESTS
using System.Collections;
using NUnit.Framework;
using UnityEngine;

public class NewRunModeTestScript
{
    // A Test behaves as an ordinary method
    [Test]
    public void NewRunModeTestScriptSimplePasses()
    {
        // Use the Assert class to test conditions
    }
}
#endif
```

てな内容のテストスクリプトをガリガリ書くだけで、別にAssembly Definationアセットを苦労して定義する必要はありません。

パスに'Editor'を含む場所においておけばEditModeのテストに、そうでなければPlayMode/Playerのテストに現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21596/34161c39-f52a-9083-5844-5b3336b0fab9.png)

テストコードを誤って製品版に残してしまう可能性も`UNITY_EDITOR || UNITY_INCLUDE_TESTS`でくくっておけば大丈夫でしょう

## テンプレートを登録する

`Assets/ScriptTemplates`（この位置でないとダメ）に
- Testing__EditMode Test Script-NewEditModeTestScript.cs.txt
- Testing__RunMode Test Script-NewRunModeTestScript.cs.txt

という名前で下記スニペットの内容のファイルを置いておけば、次回起動時から

``` NewEditModeTestScript.cs.txt
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;

public class #SCRIPTNAME#
{
    // A Test behaves as an ordinary method
    [Test]
    public void #SCRIPTNAME#SimplePasses()
    {
        // Use the Assert class to test conditions
    }

    // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
    // `yield return null;` to skip a frame.
    [UnityTest]
    public IEnumerator #SCRIPTNAME#WithEnumeratorPasses()
    {
        // Use the Assert class to test conditions.
        // Use yield to skip a frame.
        yield return null;
    }
}
```

``` NewRunModeTestScript.cs.txt
#if UNITY_EDITOR || UNITY_INCLUDE_TESTS
using System.Collections;
using NUnit.Framework;
using UnityEngine;

public class #SCRIPTNAME#
{
    // A Test behaves as an ordinary method
    [Test]
    public void #SCRIPTNAME#SimplePasses()
    {
        // Use the Assert class to test conditions
    }
}
#endif
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21596/8a558340-bf3d-4718-bb9e-1bd05920bc1f.png)

こんなふうにいつでもどこでもテンプレート生成できるメニュー項目を Assets > Create > Testing 以下に生やせられます。

## PlayMode/Playerテストでコルーチンを使ったテストをしたい場合はテストアセンブリ必須

UnityEngine.TestToolsへの参照をAssembly-CSharpに持たせられない（というか持たすべきではない）ので、テストアセンブリに所属させないテストコードではPlayMode/Playerでコルーチンを使ったテストを書けない、という制限が出ます。

が、まぁこれは我慢できる範囲かな、と。

# Tests Assembly Folder は別に必須ではない

大事なことなので二度いいました。