Version: 6000.3
语言: 中文
11. 基于场景的测试
13. 域名重新加载

12. 构建时的设置和清理

学习目标

本节将向您介绍测试框架中播放器构建前后的钩子。

介绍和动机

有时,需要在构建游戏模式测试之前更改设置或准备资产。同样,在生成后清理内容可能相关。为此,测试框架有两个连接点,称为 PrebuildSetup 和 PostBuildCleanup

在编辑器中,PrebuildSetup在构建和测试运行之前调用,并且PostBuildCleanup在测试完全完成后调用。这在编辑模式和播放模式测试中都会发生。在设备上运行播放模式测试时,清理已在构建完成后立即运行,因为测试在设备上并行进行。

确保测试具有PrebuildSetupPostBuildCleanup是通过实现IPrebuildSetupIPostBuildCleanup分别在您的测试类中。

通常,设置和清理将与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将场景添加到EditorBuildSettingsPostBuildCleanup这又删除了它。

通过在编辑器和独立播放器中运行测试来测试解决方案。您将需要使用#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.

其他资源

11. 基于场景的测试
13. 域名重新加载