Unity Test Runner 使用方法

一、创建单元测试文件夹和文件。

1. 打开 Test Runner 窗口

按照 Window -》General -》Test Runner 打开 Test Runner 窗口。
在这里插入图片描述

2. 创建单元测试文件夹

创建步骤如下图所示:
在这里插入图片描述

  1. 选中对应的模式(不同的模式功能可参考 Unity 基础 之 简单介绍与使用 单元测试 Test Runner(NUnit) / Assert 基于 2019.3.x)。
  2. 选中对应的父文件夹(此处选择Assets)。
  3. 点击按钮创建 Assembly 文件。
  4. 对新建的文件进行命名(注意,如果此时按照默认命名,同时后续再重命名文件,需要去该文件夹下的 Tests.asmdef 文件中修改对应的名称,如下图所示)
    在这里插入图片描述
    Tests.asmdef 文件中的 “name” 项的名称需要与文件夹的名称一致。

3. 创建测试脚本文件

创建步骤如下图所示:
在这里插入图片描述

  1. 选中对应的 Tests.asmdef 文件(PlayMode 对应 PlayMode 的 Tests 文件,Editor 则对应 Editor 的 Tests 文件)
  2. 此时在 Test Runner 面板下的 PlayMode 页签下,可以找到 Create Test Script ... 的相关按钮(如果选中 Tests 后没反应可以多等一会)。点击该按钮即可创建测试脚本文件。
  3. 对新建的测试文件进行命名,即可看到测试用例(下图 a 处)。
    在这里插入图片描述

二、编写测试用例

1. 编写用例代码

下方代码主要功能为点击按钮可增加点击次数,并在文本框中显示。

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace MyTestClass
{
    
    
    public class UIStudyUnitTest : MonoBehaviour
    {
    
    
        public Button btn;
        public TextMeshProUGUI txt;
        int counter = 0;
        // Start is called before the first frame update
        void Start()
        {
    
    
            this.btn.onClick.AddListener(this.on_btn_clicked);
            this.txt.text = counter.ToString();
        }

        void on_btn_clicked()
        {
    
    
            this.counter++;
            Debug.Log($"{
      
      this.counter}");
            this.txt.text = counter.ToString();
        }
    }
}

2. 编写测试用例代码

using System.Collections;
using System.Collections.Generic;
using MyTestClass;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;

public class MyPlayModeTest
{
    
    
    GameObject studyText;
    UIStudyUnitTest uiStudyText;

    [UnityTest]
    public IEnumerator MyPlayModeTestWithEnumeratorPasses()
    {
    
    
    	// 加载场景
        SceneManager.LoadScene("SampleScene");
        yield return null;

		// 获取场景中的游戏对象
        this.studyText = GameObject.Find("StudyTest");
        Assert.IsNotNull(this.studyText, "studyText should be found in the scene");

		// 获取场景中的对象上的脚步
        this.uiStudyText = this.studyText.GetComponent<UIStudyUnitTest>(); // Fix the component initialization
        Assert.IsNotNull(this.uiStudyText, "uiStudyText should be found in the game_object");

		// 模拟按钮点击,并判断是否相等。
        for (int i = 0; i < 10; i++)
        {
    
    
            Assert.AreEqual(i.ToString(), this.uiStudyText.txt.text, $"测试结果应该为{
      
      i}");
            uiStudyText.btn.onClick.Invoke();
        }
        yield return null;
    }
}

3. 引用丢失问题解决

如果在编写测试用例时,发现无法引用到游戏的相关脚本类,问题在于编译的依赖文件需要手动调整,则可进行如下操作:

  1. 在脚步文件夹下新建 Assembly Definition 文件。
    在这里插入图片描述
  2. 在测试脚本文件夹下的 .asmdef 文件下,添加游戏脚本的 Assembly Definition 文件的引用即可。
    在这里插入图片描述

4. 编写测试用例代码(无需加载场景)

采用直接实例化 Prefab 的方法,无需加载场景。

using MyTestClass;
using NUnit.Framework;
using TMPro;
using UnityEngine;

public class TestGoFromPrefab
{
    
    
    GameObject studyText;
    UIStudyUnitTest uiStudyText;

    [SetUp]
    public void setup()
    {
    
    
	    // 直接实例化 Prefab
        this.studyText = MonoBehaviour.Instantiate(Resources.Load<GameObject>("StudyTest"));
        Assert.IsNotNull(this.studyText);

        this.uiStudyText = this.studyText.GetComponent<UIStudyUnitTest>(); // Fix the component initialization
        Assert.IsInstanceOf<TextMeshProUGUI>(this.uiStudyText.txt);
    }

    [TearDown]
    public void teardown()
    {
    
    
        UnityEngine.Object.DestroyImmediate(this.studyText);
    }

    [Test]
    public void test_add()
    {
    
    
        for (int i = 0; i < 10; i++)
        {
    
    
            Assert.AreEqual(i.ToString(), this.uiStudyText.txt.text,
                $"测试结果应该为{
      
      i}");
            uiStudyText.btn.onClick.Invoke();
        }
    }
}

注意:使用 Resources.Load 进行加载时,Prefab 资源必须放在 Assets 文件夹下的 Resources 文件夹中。

三、执行测试用例

在 Test Runner 面板双击对应的测试用例即可执行。
在这里插入图片描述

参考资料

Introduction To Unity Unit Testing
HowToRunUnityUnitTest