1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PlayMakerの処理をTestRunnerで自動テストする方法

Posted at

PlayMakerの処理をTestRunnerで自動テストする方法

Variables

PlayMakerで作成した処理のテストを行う際、シーンを手動で実行して目視で確認する方法では、工数が肥大化してしまいます。

そこで、本記事では Unity標準のTestRunnerを活用して、PlayMakerの自動テストを行う方法 を解説します。
これにより、手動での検証を減らし、効率的にバグを発見できるようになります。

本記事の想定読者

本記事は、以下のような方を対象としています:

  • Unity TestRunnerC# のテストコードを書いたことがある
  • PlayMaker を使ってSTYLY向けのシーンを作ったことがある
  • PlayMakerの基本的な使い方を理解している

例題: タイム整形処理

本記事では、例題として以下の仕様の処理をテストしたいものとします。

  • 入力: float型のレースタイム(秒)
  • 出力: string型の整形済みレースタイム(ミリ秒まで0埋めで表示)
  • 処理名: TimeFormatter

具体的なテストケースとして以下を考えました。

入力 (float) 期待する出力 (string)
3 3.000
3.123456 3.123

この先の説明をシンプルにするため、テストケースはこの2つのみとします。

PlayMaker側の処理を作る

1. 作業フォルダの作成

Assets/TimeFormatter というフォルダを作成し、その中に TimeFormatterTest というシーンを作成します。

2. TimeFormatter オブジェクトの作成

シーン内に TimeFormatter というGameObjectを作成し、PlayMakerFSMをアタッチします。

GameObject

3. 変数の作成

Variablesに以下の2つの変数を作成します。

変数名
InputNumber Float
OutputString String

Variables

4. ステートマシンの構築

以下の図のように、秒数を整形する処理を作成し、処理完了後に Done ステートへ遷移するようにします。

States

今回は、 Convert Float To String アクションの FormatF3 を指定することで、小数第三位までの0埋め表示を実現します。

5. FSMの無効化

以下の図のように TimeFormatter のPlayMakerFSMを無効化します。

DisableFsm

これは、テストシーンを読み込み時にFSMが自動実行されるのを防ぐためです。
あくまでテストシーン専用の設定なので、プレハブを利用している場合、この設定をOverrideする必要はありません。

テストコードを作る

1. テスト用フォルダの作成

作業フォルダ配下に Tests フォルダを作成し、その中に TimeFormatterTest.cs を作成します。

2. テストコードの実装

using System;
using System.Collections;
using NUnit.Framework;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;

namespace Segur.TimeFormatter.Tests
{
    public class TimeFormatterTest
    {
        private const string SceneName = "TimeFormatterTest";
        private const string GameObjectName = "TimeFormatter";
        private PlayMakerFSM fsm;

        [UnitySetUp]
        private IEnumerator Setup()
        {
            // シーンを探す
            var guids = AssetDatabase.FindAssets("t:scene " + SceneName);
            if (guids.Length != 1)
            {
                throw new Exception("Scene name is not unique.");
            }

            // シーンを読み込む
            var path = AssetDatabase.GUIDToAssetPath(guids[0]);
            EditorSceneManager.LoadSceneInPlayMode(path, new LoadSceneParameters(LoadSceneMode.Single));
            yield return null;

            // FSMを探す
            var gameObject = GameObject.Find(GameObjectName);
            fsm = gameObject.GetComponent<PlayMakerFSM>();
        }

        private IEnumerator RunTest(float inputNumber, string expectedOutput)
        {
            // 入力変数を設定
            fsm.FsmVariables.FindFsmFloat("InputNumber").Value = inputNumber;

            // FSMを実行
            fsm.enabled = true;

            // StateがDoneになるまで待機する。5秒でタイムアウト
            var elapsedTime = 0f;
            while (fsm.ActiveStateName != "Done" && elapsedTime < 5f)
            {
                yield return null;
                elapsedTime += Time.deltaTime;
            }

            // Stateを検証。タイムアウトしていたら不合格になる
            Assert.That(fsm.ActiveStateName, Is.EqualTo("Done"));

            // 出力変数を検証
            Assert.That(fsm.FsmVariables.FindFsmString("OutputString").RawValue, Is.EqualTo(expectedOutput));
        }

        [UnityTest]
        public IEnumerator FormatsWholeNumberCorrectly()
        {
            yield return RunTest(3f, "3.000");
        }

        [UnityTest]
        public IEnumerator FormatsDecimalNumberCorrectly()
        {
            yield return RunTest(3.12345f, "3.123");
        }
    }
}

このテストでは、PlayMakerの変数 (Variables) を介してFSMを操作し、期待通りの出力になるかを検証しています。

PlayMode Test を有効にする設定

デフォルトでは asmdef を作成しないと NUnit の参照エラーが発生しますが、以下の設定を変更することでエラーを解消できます。

設定手順

ProjectSettings/ProjectSettings.asset をテキストエディターで開き、以下の設定を 1 に変更してください。

playModeTestRunnerEnabled: 1

これにより、asmdef なしでも PlayMode Test を実行できます。 1

テストを実行する

TestRunnerのPlayModeタブを開き、作成したテストを実行します。

TestRunner

すべてのテストが合格すれば、PlayMakerの処理が正しく動作していることが確認できます!

おつかれさまでした!

さいごに

本記事に掲載した手法は、 @kotauchisunsun 氏が考案したアイデアをもとにしています。
この場を借りて感謝いたします。ありがとうございました。

  1. この設定をするとビルドした際にテストコードが含まれてしまう恐れがあります。ただ、今回の読者はSTYLYシーン制作者を想定しており、アプリビルドはしないため、問題はないと考えています。また、シンボル定義によってこの問題は回避できることもわかっています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?