はじめに
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を指定できるなら指定しておきましょう。