前回は自作の影用タイルマップ作成関数をテストするために、その関数に与える処理前の壁のタイルマップと、関数で処理して影に見えるように変形した影用タイルマップを Unity エディタ上で GUI を用いて作成し、プレハブ化しました。
今回は、その答え合わせ用のタイルマップの入ったプレハブをインスタンス化し、テスト対象の関数が処理したタイルマップとあらかじめ用意しておいたプレハブのタイルマップを比較して、処理が正しくできているかテストします。
※ Unity は 2021.3.14f1、Test Framework パッケージは Version 1.1.33、Visual Studio は Community 版 Version 17.2.5、 OS は Windows 10 です。
テスト用のコードの説明
以下が、影用タイルマップ作成関数 SCTransformDownwardShadowAllTiles のテスト関数のコードです。
/// <summary>
/// SCTilemapExtensions の SCTransformDownwardShadowAllTiles 関数のテストです。
/// 手動で作成した正解のタイルマップのプレハブとタイルの配置・表示設定が一致するか確認します。
/// 前提条件は、SCTilemapExtensions_SCIsSameTileBlockLayout_1 のテストに合格していることです。
/// </summary>
/// <param name="grid3PrefabPath">wallsTilemap と wallsShadowTilemap を持つ Grid オブジェクトのプレハブのパスです</param>
/// <param name="wallsTilemapName">Grid オブジェクトの直下にある壁を配置したタイルマップの名前です。</param>
/// <param name="wallsShadowTilemapName">Grid オブジェクトの直下にある影用タイルマップの名前です。</param>
/// <param name="translateY">影として位置を調整する際の Y 軸の移動量です。</param>
/// <param name="scaleY">タイルの Y 軸の拡大率です。大きいほど伸びた影になります。</param>
/// <param name="correctTranslateY"> Y 軸の移動量を自動調整する場合は true を指定します。pivot や scaleY の値が考慮されます。translateY は無視されます。</param>
[TestCase("Test/Tilemap/TestGrid3", "WallsTilemap1", "WallsShadowTilemap1", -0.75f, 0.5f, true)]
public void SCTilemapExtensions_SCTransformDownwardShadowAllTiles(
string grid3PrefabPath, string wallsTilemapName, string wallsShadowTilemapName, float translateY, float scaleY, bool correctTranslateY)
{
// (1) 指定されたパスのプレハブをインスタンス化し、テストに用いるタイルマップ 2 つを得ます。
GameObject grid3Prefab = Resources.Load(grid3PrefabPath) as GameObject;
Assert.That(grid3Prefab, Is.Not.Null);
GameObject grid3Go = GameObject.Instantiate(grid3Prefab);
Assert.That(grid3Go, Is.Not.Null);
// (2) インスタンス化したゲームオブジェクトから下位の 2 つのゲームオブジェクトを取得します。
// 下位のゲームオブジェクトに付加されているタイルマップコンポーネントを取得します。
GameObject wallsTilemapGo = grid3Go.transform.Find(wallsTilemapName).gameObject;
Assert.That(wallsTilemapGo, Is.Not.Null);
GameObject wallsShadowTilemapGo = grid3Go.transform.Find(wallsShadowTilemapName).gameObject;
Assert.That(wallsShadowTilemapGo, Is.Not.Null);
Tilemap wallsTilemapCo = wallsTilemapGo.GetComponent<Tilemap>();
Assert.That(wallsTilemapCo, Is.Not.Null);
Tilemap wallsShadowTilemapCo = wallsShadowTilemapGo.GetComponent<Tilemap>();
Assert.That(wallsShadowTilemapCo, Is.Not.Null);
// (3) テスト対象の関数を呼び出します。壁タイルマップのタイルを影用タイルマップのタイルに変形(垂直反転、拡大、オフセット)します。
List<TilemapExtentions.SCTransformDownwardShadowCorrectInfo> infoList = new List<TilemapExtentions.SCTransformDownwardShadowCorrectInfo>();
wallsTilemapCo.SCTransformDownwardShadowAllTiles(translateY, scaleY, correctTranslateY, infoList);
// (4) プレハブから得た影用タイルマップと、関数で変形したタイルマップを比較して同じならばテストはクリアです。
bool actual = wallsTilemapCo.SCIsSameTileBlockLayout(wallsShadowTilemapCo);
Assert.That(actual, Is.EqualTo(true));
}
主要な機能を説明します。
[TestCase] による引数の指定
関数の前にある [TestCase(…)] は Unity の Test Framework で Test Runner ウィンドウから実行できるテスト関数であることを示す属性です。
[Test] や [UnityTest] などもありますが、 TestCase を使うことで任意の引数をテスト関数に与えることができます。
今回は、テストで用いるタイルマップが含まれている Grid のプレハブへのパス、2 つのタイルマップ名、影を作るために必要なパラメータである拡大率やオフセットについて指定しています。
プレハブのロードとインスタンス化
コードのコメントの (1) の部分です。
最初に Resources.Load 関数を用いて指定されたパスのプレハブをロードします。
Resources.Load 関数は Resources という名前のフォルダの中のアセットにしかアクセスできないので注意しましょう。
その後、ロードしたプレハブをインスタンス化します。
プレハブからタイルマップを取り出す
コードのコメントの (2) の部分です。
指定されたゲームオブジェクト名により transform 経由で TestGrid3 ゲームオブジェクトの下位のゲームオブジェクトを検索しています。
下位のゲームオブジェクトにはタイルマップコンポーネントが付加されているので、GetComponent 関数で取得します。
影用タイルマップ作成関数の実行
コードのコメントの (3) の部分です。
取得したタイルマップコンポーネントは、壁のタイルマップと、影用のタイルマップです。
どちらも Unity エディタ上で GUI を用いて作りました。
影用タイルマップの元となる、壁のタイルマップをテスト対象の関数に渡し、影用タイルマップのタイルへと変形させます。
タイルマップの比較テスト
上図のように、テスト対象の影用タイルマップ作成関数で変形させられたタイルマップと、 Unity エディタ上で作ってプレハブにしておいた影用タイルマップを比較します。
同じならばテストは合格です。
テストの実行と結果
メニュー[Window]→[General]→[Test Runner] を選択し Test Runner ウィンドウを表示します。
作成したテスト関数をツリーリストの中から探し、実行します。
テストが成功した結果、緑色のチェックマークが表示されました。
Assert の比較関数
今回は影用タイルマップ作成関数の具体的なテスト用コードを紹介しましたが、 Assert には他にも様々なテスト用の関数があります。
Unity 公式マニュアルに Assert の static 関数の一覧があるので引用します。
https://docs.unity3d.com/ja/2021.1/ScriptReference/Assertions.Assert.html
AreApproximatelyEqual Assert the values are approximately equal. AreEqual Assert that the values are equal. AreNotApproximatelyEqual Asserts that the values are approximately not equal. AreNotEqual Assert that the values are not equal. IsFalse Return true when the condition is false. Otherwise return false. IsNotNull Assert that the value is not null. IsNull Assert the value is null. IsTrue true となる条件のアサート Assertions.Assert – Unity スクリプトリファレンス
また、.NET のテストで用いられる NUnit の比較の関数も利用できます。
詳しくは NUnit の公式ドキュメントを参照してください。
また、文字列、コレクション、ファイル、ディレクトリに関するテスト機能は、それぞれ特化した Assert クラスで提供しています。
- StringAssert | NUnit Docs
- CollectionAssert | NUnit Docs
- FileAssert | NUnit Docs
- DirectoryAssert | NUnit Docs
- Unity のリアルタイム開発プラットフォーム | 3D/2D、VR/AR のエンジン
- Test Framework – Unity マニュアル
- Unity Test Runner でのテストの作成と実行 – Unity マニュアル
- C# 単体テスト チュートリアル – Visual Studio (Windows) | Microsoft Learn
- [Unity] C#クラス(スクリプト)のテスト方法 | ソフトライム
- Assertions.Assert – Unity スクリプトリファレンス
- Assertions | NUnit Docs
テストをする際は、様々な比較関数が提供されているので、適したものを使うと良いでしょう。
まとめ
今回は、Unity の Tilemap コンポーネントを利用する、影用タイルマップ作成関数のテストのために、答え合わせ用のタイルマップをプレハブからロード・インスタンス化し、比較するコードや手順を紹介しました。
Assert や NUnit の機能にはさまざまな比較関数があることもリンクで紹介しました。
コメント