Cooooding!!

Unity(C#)を使ったゲーム開発関連Tipsなど

TestRunnerでLogErrorや例外が発生することをテストする【Unity】

概要

TestRunnerで例外が発生することをテストするのはNUnit.Framework.Assert.Catchでできますが LogErrorのテストはできません。指定した文字列のLogErrorが出力されることをテストするのはTestTools.LogAssertでできますが、前回の記事で書いたように少し扱い辛い仕様になっています。そこでNUnit.Framework.Assert.Catchのようなインターフェースで使えてLogErrorもテストできる関数を実装してみました。

実装

/// <summary>
/// 何らかのエラー(LogError/例外)が発生されることを確認する
/// </summary>
public static void ErrorOccurs(TestDelegate code)
{
    LogAssert.ignoreFailingMessages = true; // LogErrorの出力でテストが失敗しないように
    bool error = false;                     // エラーが発生したかどうかのフラグ
    // ログ出力イベント処理用のローカル関数
    void OnLogMessage(string logString, string stackTrace, LogType logType)
    {
        switch(logType)
        {
            case LogType.Assert:
            case LogType.Exception:
            case LogType.Error:
                error = true;
                break;
        }
    };

    Application.logMessageReceived += OnLogMessage;
    try
    {
        code.Invoke();  // 引数で渡されたDelegateを実行
    }
    catch(System.Exception e)
    {
        UnityEngine.Debug.LogException(e);
    }
    Application.logMessageReceived -= OnLogMessage;
    LogAssert.ignoreFailingMessages = false;
    
    if (!error)
    {
        Assert.Fail("エラーが発生しませんでした");
    }
}

使用例

[Test]
public void ErrorOccurs_LogError()
{
    ErrorOccurs(() => { Debug.LogError("エラー!!"); });
}

[Test]
public void ErrorOccurs_Exception()
{
    ErrorOccurs(() => { throw new System.Exception("例外!!"); });
}

[Test]
public void ErrorOccurs_Nothing()
{
    ErrorOccurs(() => { });     // エラーが発生しないのでテストに失敗する
}

環境

  • Unity 2019.1.9f1
  • VisualStudio 2019