やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

Unity x WebGLのテストTips

今週は、Unity 1週間ゲームジャム 第22回が開催されています。 今回のお題は「そろえる」とのことで、何かをそろえたら消えて得点が入るような振る舞いの自動テストを書きたくなる方もいるのではないでしょうか。

Unity 1週間ゲームジャムの投稿先であるフリーゲーム投稿サイトunityroomには、プラットフォームに「WebGL」を選択してビルド・アップロードを行ないます。 WebGLプラットフォームには、一部Unity Test Frameworkの制限があります。そのあたりを改めて検証してみました。

検証環境

  • Unity 2021.3.1f1
  • Unity Test Framework 1.1.31

Unity 2020以前の場合、本記事に記載していない問題を確認しています*1。 また、Unity 2021.3ではWebGLのビルドがかなり早くなっています*2。 どうしても古いバージョンを使わなければならない事情でもない限り、Unity 2021.3で開発することをおすすめします。

Edit ModeテストおよびIn Editor実行の制限

Edit Modeテストおよび、Play ModeテストをUnityエディター上で実行する限り、プラットフォームがWebGLであっても制限はありません。 そしてほとんどの場合、テストはUnityエディター上で動作させれば十分です。 つまり、

勝ったッ! 第3部完!

ということで、以下はおまけです。

プレイヤー実行の制限

本セクションの制限事項は、Unityエディター側の対応により Unity 2020.3.42f1, 2021.3.8f1, 2022.1.12f1, 2022.2.0b3, 2023.1.0a4 では解消しています。 詳しくは次の記事を参照してください [2023/1/6]

www.nowsprinting.com

Test Runnerウィンドウで「PlayMode」を選択しているとき、ウィンドウ右上にある「Run All Tests(WebGL*3)」をクリックすると下図のようにWebブラウザが開き、その中でWebGLアプリケーションとしてテストが実行されます。

以下、WebGLプレイヤー実行における問題点と制限事項を紹介します。

テスト実行結果がTest Runnerウィンドウに反映されない

他のプラットフォームではテスト実行結果はTest Runnerウィンドウに反映されますが、WebGLではされません。 "Receiving test data from player" と表示されるプログレスバーが止まったままとなり、キャンセルするしかありません。

どのテストが失敗したかを知るには、ブラウザ上のメッセージを読み取るか、WebブラウザJavaScriptコンソールでログを読むしかないようです。

docs.unity3d.com

UnityTest属性を使用できない

これはUnity Test Frameworkのドキュメントにも記載されている公の制限事項です。 UnityTest属性による非同期テストをWebGLプレイヤーで実行すると、 "Unhandled log message: '[Error] [xxx] The message header is corrupted and for security reasons connection will be terminated.'. Use UnityEngine.TestTools.LogAssert.Expect" というメッセージで失敗します。これはテスト実行中にLogErrorが吐かれたことに起因するメッセージであり、肝心のLogErrorで何が書かれているかは読み取れません。

この問題を回避するには、UnityTest属性で書かれたテストをWebGLプレイヤーで実行しないよう、次のようにUnityPlatform属性のexcludeパラメーターで除外指定します。

[UnityTest]
[UnityPlatform(exclude = new[] { RuntimePlatform.WebGLPlayer })]
public IEnumerator 非同期テストメソッド()
{
    _cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    yield return null;

    Assert.That((bool)_cube, Is.True);
}

このテストはWebGLプレイヤーでは実行されなくなります。同等のテストをWebGLプレイヤーでも実行したいのであれば、なんとか同期テストとして書き直すしかありません。

UnitySetUp属性を使用できない

これも恐らくUnityTest属性と同じ理由で使用できないようです。 しかし、UnityTearDown属性は(Unity Test Framework v1時点では)WebGLでも動作します。ふしぎ。

こちらはSetUpメソッドのみ除外指定しても意味ないはずなので、UnityPlatform属性をテストクラスにつけることでクラスごと除外指定するとよいでしょう。

なお、UnityPlatform属性はメソッド、クラスのほか、アセンブリにも指定できます。

Unity Test Framework v2での制限

続いて、Unity Test Framework 2.0.1-pre.18を使っての検証結果です。プレリリース版ですので、今後緩和される可能性はあります。

非同期テストのサポートが最大の売りであるUnity Test Framework v2ですが、上記v1の制限事項は引き続き残り、追加で以下の制限があります。

非同期テストは使用できない

v2で追加された非同期テスト(async tests)ですが、これもWebGLでは使用できないようです。

UnityTearDown属性を使用できない

v1ではなぜか使用できたUnityTearDown属性は、v2では使用できなくなったようです。

まとめ

WebGLのテストは、Unityエディター上で実行する限り問題なし!

参考

Unity Test Frameworkについてはこちらの同人誌を参照してください。Unity Test Framework v2対応となる第2版に無償アップデートを予定していますので、買い控える必要はありません!

www.nowsprinting.com

Unity Test Framework v2についてはこちらを参照。

www.nowsprinting.com

*1:発生条件や修正されたバージョンの特定まで行なう時間がなく未調査です

*2:これも正確にどのバージョンからかは未調査です

*3:WebGL」部分は現在選択されているプラットフォーム名が入ります