はじめに
UnityのEditTestでasync/awaitが使いたい!ということで使い方を調べました。
やり方
大きく分けて2つあります。
-
[UnityTest]+UniTask.ToCoroutineを使う - UnityTestFramework 1.3.8以降を使う
[UnityTest] + UniTask.ToCoroutineを使う方法
[UnityTest](コルーチンベースのテスト)にUniTask.ToCoroutineを組み合わせることで、async/awaitをEditTestで利用できるようになります。
using System;
using System.Collections;
using Cysharp.Threading.Tasks;
using NUnit.Framework;
using UnityEngine.TestTools;
namespace TORISOUP.Tests
{
[TestFixture]
public class SampleTest
{
[UnityTest]
public IEnumerator 非同期テスト() => UniTask.ToCoroutine(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(1));
Assert.AreEqual(1, 1);
});
}
}
メリット
- UnityTestFramework 1.1.33(標準で導入されている安定版)で利用できる
デメリット
-
UniTaskの導入が必要 - TimeoutAttributeが使えない
UnityTestFramework 1.3.8以降を使う方法
事前導入
"com.unity.test-framework": "1.3.8",
UnityTestFramework 1.3.8はまだstableではないため非推奨パッケージとなっています。
導入の場合はmanifest.jsonを書き換えて1.3.8を導入する必要があります。
非同期テスト
UnityTestFramework 1.3.8以降であれば[Test]を使ってasync/awaitが記述できます。
([UnityTest]では使えない)
using System;
using System.Threading.Tasks;
using NUnit.Framework;
namespace TORISOUP.Tests
{
[TestFixture]
public class SampleTest
{
[Test]
public async Task 非同期テスト()
{
await Task.Delay(TimeSpan.FromSeconds(1));
Assert.AreEqual(1, 1);
}
}
}
メリット
- UniTaskの導入が不要
- TimeoutAttributeによりタイムアウトを指定することができる
デメリット
- UnityTestFramework 1.3.8(まだ非推奨パッケージ)が必要
最後に
どちらもBatchModeで動かすときはrunSynchronously = falseである必要があります。
補足
EditTest + BatchMode の環境で、UniTask.Delayなどを用いるとawaitが完了せずに無限待機にハマる可能性があります(原因不明。起きるプロジェクトと起きないプロジェクトがある。)
そのためテスト上では Task.Delay を使ったほうが安全かも。
また無限awaitしてしまうとタイムアウトまで180秒待たされることになるので、TimeoutAttributeを指定できるなら指定しておきましょう。