Unity Test Runnerの使い方
よくわからないままUnityのテスト・コードを書いてみた. SetUpとTearDownはいらなかった気がする. GameObject.Destroy()だとDestroyImmediateを使えって怒られた.
using NUnit.Framework;
using UnityEngine;
using TMPro;
public class MaxThreeNumbersTest {
private GameObject element1, element2, element3;
[SetUp]
public void SetUp() {
element1 = new GameObject("Element0");
element1.AddComponent<TextMeshPro>();
element1.GetComponent<TextMeshPro>().text = "1";
element2 = new GameObject("Element1");
element2.AddComponent<TextMeshPro>();
element2.GetComponent<TextMeshPro>().text = "15";
element3 = new GameObject("Element2");
element3.AddComponent<TextMeshPro>();
element3.GetComponent<TextMeshPro>().text = "9";
}
[Test]
public void ReturnMaxOfThreeNumbers() {
var values = new int[] {
int.Parse(element1.GetComponent<TextMeshPro>().text),
int.Parse(element2.GetComponent<TextMeshPro>().text),
int.Parse(element3.GetComponent<TextMeshPro>().text)
};
var maxIndex = MaxThreeNumbers.Max(values);
var got = values[maxIndex];
var expected = 15;
Assert.AreEqual(got, expected);
}
[TearDown]
public void TearDown() {
GameObject.DestroyImmediate(element1);
GameObject.DestroyImmediate(element2);
GameObject.DestroyImmediate(element3);
}
}
GameObject.Destroy()だとDestroyImmediateを使えって怒られた
GameObject.Destroy()
はPlayModeでしか使用できません。そのため、EditModeでテストを行う場合は GameObject.DestroyImmediate()
を使用する必要があります。
エディタ・モードのテストでUnityTest属性を使うのは, IEditModeTestYieldInstructionを実装して使うとき.
それ以外はプレイ・モードに主に使う.
NUnitのAssertionsによると3.0以降はAssert.Thatメソッドを使う方向で統一しているんですね.
TestCaseSourceのパラメータが渡せない
テストケースとしてランダムな数値列を生成するのにTestCaseSourceを使ってみたが, 引数の渡し方がよくわからない. いろいろよくわからないので供養しておく.
using System.Collections.Generic;
using NUnit.Framework;
public class ReverseArrayTest {
const int MAX = 100;
const int ARRAY_SIZE = 5;
[Test]
[TestCaseSource(nameof(RandomArrays), new int[] { 10, 7, 12 })]
public void ReverseArrayOrder(int[] arr) {
int firstElement = arr[0];
// int lastElement = arr[ARRAY_SIZE - 1];
// int middleElement = arr[ARRAY_SIZE / 2];
int[] rev_arr = ReverseArray.Reverse(arr);
Assert.That(firstElement, Is.EqualTo(rev_arr[ARRAY_SIZE - 1]));
// Assert.That(lastElement, Is.EqualTo(rev_arr[0]));
// Assert.That(middleElement, Is.EqualTo(rev_arr[ARRAY_SIZE / 2]));
}
static IEnumerable<int[]> RandomArrays(int[] array_sizes) {
yield return GenRandomArray(array_sizes[0]);
yield return GenRandomArray(array_sizes[1]);
yield return GenRandomArray(array_sizes[2]);
}
static int[] GenRandomArray(int array_size = ARRAY_SIZE) {
int[] randomArray = new int[array_size];
var rnd = new System.Random();
for (int i = 0; i < array_size; i++) {
randomArray[i] = rnd.Next(MAX);
}
return randomArray;
}
}
大分経過していますが、なんとなく気になったので書いてみました。
TestCaseSourceAttribute
ですが、これは入力 (引数)を TestCaseData
として格納する必要があります。
また今回はvoid
なので書いていませんが、TestCaseData
は、テスト関数を実行した際の正しい戻り値も指定できます。
一方で、テスト関数の引数に値を指定できる ValueSourceAttribute
というのもあります。
もし複数の引数があり、その組み合わせによるテストが欲しい場合に活用できますよ。
using System;
using System.Collections.Generic;
using NUnit.Framework;
public class ReverseArrayTest {
private const int MAX = 100;
private const int ARRAY_SIZE = 5;
private static IEnumerable<int[]> RandomArray {
get {
foreach (int array_size in new[] { 10, 7, 12 }) {
yield return GenRandomArray(array_size);
}
}
}
private static IEnumerable<TestCaseData> RandomArrayTestCaseDatas {
get {
foreach (int array_size in new[] { 10, 7, 12 }) {
yield return new TestCaseData(GenRandomArray(array_size));
}
}
}
/// <summary>
/// <see cref="ValueSourceAttribute" />を使用した、引数にテストケースとなる値を入れるサンプルです
/// </summary>
/// <param name="arr"></param>
[Test]
public void ReverseArrayOrder_FromParams([ValueSource(nameof(RandomArray))] int[] arr) {
int firstElement = arr[0];
// int lastElement = arr[ARRAY_SIZE - 1];
// int middleElement = arr[ARRAY_SIZE / 2];
int[] rev_arr = ReverseArray.Reverse(arr);
Assert.That(firstElement, Is.EqualTo(rev_arr[ARRAY_SIZE - 1]));
// Assert.That(lastElement, Is.EqualTo(rev_arr[0]));
// Assert.That(middleElement, Is.EqualTo(rev_arr[ARRAY_SIZE / 2]));
}
/// <summary>
/// <see cref="TestCaseSourceAttribute" /> を使用した、テストケース生成のサンプルです
/// </summary>
/// <param name="arr"></param>
[Test]
[TestCaseSource(nameof(RandomArrayTestCaseDatas))]
public void ReverseArrayOrder_FromTestCase(int[] arr) {
int firstElement = arr[0];
// int lastElement = arr[ARRAY_SIZE - 1];
// int middleElement = arr[ARRAY_SIZE / 2];
int[] rev_arr = ReverseArray.Reverse(arr);
Assert.That(firstElement, Is.EqualTo(rev_arr[ARRAY_SIZE - 1]));
// Assert.That(lastElement, Is.EqualTo(rev_arr[0]));
// Assert.That(middleElement, Is.EqualTo(rev_arr[ARRAY_SIZE / 2]));
}
/// <summary>
/// ランダムな配列を生成します
/// </summary>
/// <param name="array_size"></param>
/// <returns></returns>
private static int[] GenRandomArray(int array_size = ARRAY_SIZE) {
int[] randomArray = new int[array_size];
Random rnd = new Random();
for (int i = 0; i < array_size; i++) {
randomArray[i] = rnd.Next(MAX);
}
return randomArray;
}
}
例題まで載せていただき感謝です.