包含此页的版本:
不含此页的版本:
本节将向您介绍测试框架中播放器构建前后的钩子。
有时,需要在构建游戏模式测试之前更改设置或准备资产。同样,在生成后清理内容可能相关。为此,测试框架有两个连接点,称为 PrebuildSetup 和 PostBuildCleanup。
在编辑器中,PrebuildSetup在构建和测试运行之前调用,并且PostBuildCleanup在测试完全完成后调用。这在编辑模式和播放模式测试中都会发生。在设备上运行播放模式测试时,清理已在构建完成后立即运行,因为测试在设备上并行进行。
确保测试具有PrebuildSetup和PostBuildCleanup是通过实现IPrebuildSetup和IPostBuildCleanup分别在您的测试类中。
通常,设置和清理将与UnityEditor组件。这些在设备上运行时不可用,但我们希望内置的设置和清理代码保留在测试类中。为此,建议将与编辑器相关的代码行包装在#if UNITY_EDITOR定义。例如:
public class MyTestClass : IPrebuildSetup
{
[Test]
public void MyTest()
{
}
public void Setup()
{
#if UNITY_EDITOR
UnityEditor.EditorSettings.serializationMode = SerializationMode.ForceText;
#endif
}
}
注意:如果编辑器代码未包装,则在编辑器中运行时不会看到任何编译错误,但一旦您尝试在播放器中运行测试,您就会看到编译错误。
示例12_BuildSetupCleanup包含一个播放模式测试,用于验证场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表.它本质上是上一个练习中测试的“播放模式”版本。
测试失败,因为找不到场景。可以通过将场景添加到构建设置来解决此问题,但将与测试相关的场景添加到构建设置中并不是一个好的做法,因为它可能会在出于非测试目的进行构建时被包含。
因此,任务是创建一个PrebuildSetup将场景添加到EditorBuildSettings和PostBuildCleanup这又删除了它。
通过在编辑器和独立播放器中运行测试来测试解决方案。您将需要使用#if UNITY_EDITOR使代码为播放器编译。
IPrebuildSetup接口需要Setup方法,所以要注意没有[SetUp]方法已经调用了它。示例中提供了完整的解决方案 12_BuildSetupCleanup_Solution.
完整的测试解决方案可以这样完成:
using System.Collections;
using System.Linq;
using NUnit.Framework;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;
namespace Tests
{
public class SceneTests : IPrebuildSetup, IPostBuildCleanup
{
private string originalScene;
private const string k_SceneName = "Assets/MyGameScene.unity";
public void Setup()
{
#if UNITY_EDITOR
if (EditorBuildSettings.scenes.Any(scene => scene.path == k_SceneName))
{
return;
}
var includedScenes = EditorBuildSettings.scenes.ToList();
includedScenes.Add(new EditorBuildSettingsScene(k_SceneName, true));
EditorBuildSettings.scenes = includedScenes.ToArray();
#endif
}
[UnitySetUp]
public IEnumerator SetupBeforeTest()
{
originalScene = SceneManager.GetActiveScene().path;
SceneManager.LoadScene(k_SceneName);
yield return null; // Skip a frame
}
[Test]
public void VerifyScene()
{
var gameObject = GameObject.Find("GameObjectToTestFor");
Assert.That(gameObject, Is.Not.Null, $"GameObjectToTestFor not found in {SceneManager.GetActiveScene().path}.");
}
[TearDown]
public void TeardownAfterTest()
{
SceneManager.LoadScene(originalScene);
}
public void Cleanup()
{
#if UNITY_EDITOR
EditorBuildSettings.scenes = EditorBuildSettings.scenes.Where(scene => scene.path != k_SceneName).ToArray();
#endif
}
}
}
请注意#if UNITY_EDITOR也用于 using 语句,以允许对UnityEditor.