使用协程设置进行播放模式测试
PlayMode Tests with Coroutine SetUp
我是 Unity3D 测试的新手,我想为我们的游戏编写一些测试。我设法编写了这个有效的测试 fine:
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Game.Characters;
using Game.Inventory;
namespace Tests
{
public class ItemTests
{
[UnityTest]
public IEnumerator ItemIsOnHand()
{
// Setup
Player player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
yield return null; // Wait for prefab to load
Character character = player.GetComponent<Character>();
WorldItem worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
yield return null; // Wait for prefab to load
character.Inventory.Give(worldItem);
ItemScript itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
// Test
Assert.IsNotNull(itemScript);
// Teardown
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(worldItem);
Object.Destroy(itemScript);
}
[UnityTest]
public IEnumerator ItemIsDisabledAtStart()
{
// Setup
Player player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
yield return null; // Wait for prefab to load
Character character = player.GetComponent<Character>();
WorldItem worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
yield return null; // Wait for prefab to load
character.Inventory.Give(worldItem);
ItemScript itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
// Test
Assert.IsFalse(itemScript.IsActive);
// Teardown
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(worldItem);
Object.Destroy(itemScript);
}
}
}
如您所见,这两个测试(以及其他测试)都使用相同的设置和拆卸。我在方法之外声明变量(可用于每个测试)。拆解方法工作正常,因为它不需要等待任何加载。
private Player player;
private Character character;
private WorldItem worldItem;
private ItemScript itemScript;
[TearDown]
public void Teardown()
{
Debug.Log("Teardown called");
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(ectomodulatorWorldItem);
}
但我无法使 SetUp 方法起作用。如果我将它设为协程 ([SetUp] public IEnumerator SetUp(){...}
),它永远不会运行(我用调试器检查过)。如果我使它成为一个简单的 void 方法并删除 yield return null
s,它会在 character.Inventory.Give(worldItem);
处失败,因为 worldItem
仍然是 null
.
有没有办法让 SetUp 方法起作用?
谢谢
我找到了我需要的东西。就像 [Test]
属性只适用于 void
方法,你需要使用 [UnityTest]
到 运行 一个协程,还有一个 [UnitySetUp]
属性允许使用协程设置而不是 void
一个。
Link 到文档获取更多信息:https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/reference-actions-outside-tests.html#unitysetup-and-unityteardown
如果你有兴趣,我的测试文件是这样的:
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Game.Characters;
using Game.Inventory;
namespace Tests
{
public class ItemTests
{
Player player;
Character character;
WorldItem worldItem;
ItemScript itemScript;
[UnitySetUp]
public IEnumerator SetUp()
{
player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
yield return null; // Wait for prefab to load
character = player.GetComponent<Character>();
worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
yield return null; // Wait for prefab to load
character.Inventory.Give(worldItem);
itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
}
[TearDown]
public void Teardown()
{
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(ectomodulatorWorldItem);
}
[Test]
public void ItemIsOnHand()
{
// Test
Assert.IsNotNull(itemScript);
}
[Test]
public void ItemIsDisabledAtStart()
{
// Test
Assert.IsFalse(itemScript.IsActive);
}
}
}
我是 Unity3D 测试的新手,我想为我们的游戏编写一些测试。我设法编写了这个有效的测试 fine:
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Game.Characters;
using Game.Inventory;
namespace Tests
{
public class ItemTests
{
[UnityTest]
public IEnumerator ItemIsOnHand()
{
// Setup
Player player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
yield return null; // Wait for prefab to load
Character character = player.GetComponent<Character>();
WorldItem worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
yield return null; // Wait for prefab to load
character.Inventory.Give(worldItem);
ItemScript itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
// Test
Assert.IsNotNull(itemScript);
// Teardown
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(worldItem);
Object.Destroy(itemScript);
}
[UnityTest]
public IEnumerator ItemIsDisabledAtStart()
{
// Setup
Player player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
yield return null; // Wait for prefab to load
Character character = player.GetComponent<Character>();
WorldItem worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
yield return null; // Wait for prefab to load
character.Inventory.Give(worldItem);
ItemScript itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
// Test
Assert.IsFalse(itemScript.IsActive);
// Teardown
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(worldItem);
Object.Destroy(itemScript);
}
}
}
如您所见,这两个测试(以及其他测试)都使用相同的设置和拆卸。我在方法之外声明变量(可用于每个测试)。拆解方法工作正常,因为它不需要等待任何加载。
private Player player;
private Character character;
private WorldItem worldItem;
private ItemScript itemScript;
[TearDown]
public void Teardown()
{
Debug.Log("Teardown called");
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(ectomodulatorWorldItem);
}
但我无法使 SetUp 方法起作用。如果我将它设为协程 ([SetUp] public IEnumerator SetUp(){...}
),它永远不会运行(我用调试器检查过)。如果我使它成为一个简单的 void 方法并删除 yield return null
s,它会在 character.Inventory.Give(worldItem);
处失败,因为 worldItem
仍然是 null
.
有没有办法让 SetUp 方法起作用?
谢谢
我找到了我需要的东西。就像 [Test]
属性只适用于 void
方法,你需要使用 [UnityTest]
到 运行 一个协程,还有一个 [UnitySetUp]
属性允许使用协程设置而不是 void
一个。
Link 到文档获取更多信息:https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/reference-actions-outside-tests.html#unitysetup-and-unityteardown
如果你有兴趣,我的测试文件是这样的:
using System.Collections;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Game.Characters;
using Game.Inventory;
namespace Tests
{
public class ItemTests
{
Player player;
Character character;
WorldItem worldItem;
ItemScript itemScript;
[UnitySetUp]
public IEnumerator SetUp()
{
player = MonoBehaviour.Instantiate(Resources.Load<GameObject>("Tests/Player"));
yield return null; // Wait for prefab to load
character = player.GetComponent<Character>();
worldItem = WorldItem.Create(Resources.Load<Item>("Items/item"), 1);
yield return null; // Wait for prefab to load
character.Inventory.Give(worldItem);
itemScript = character.HandItemContainer.gameObject.GetComponentInChildren<ItemScript>();
}
[TearDown]
public void Teardown()
{
Object.Destroy(player);
Object.Destroy(character);
Object.Destroy(ectomodulatorWorldItem);
}
[Test]
public void ItemIsOnHand()
{
// Test
Assert.IsNotNull(itemScript);
}
[Test]
public void ItemIsDisabledAtStart()
{
// Test
Assert.IsFalse(itemScript.IsActive);
}
}
}