原文地址:1. Unity3D 單元測試框架介紹
Unity3D 簡要介紹
如果是游戲行業的同學估計就沒有不知道 Unity3D 的,騰訊的王者榮耀就是基於 Unity3D(簡稱:U3D)來開發的。在 U3D 中,有三個基本的概念:游戲場景(Scene)、游戲物體(GameObject)和組件(Component)。我們可以借用電影來理解這三個概念,整部電影從開始到結束,由很多場景組成,比如動作電影中的打斗場景在廢舊的工廠中進行,廢舊的工廠就是游戲場景;廢舊工廠中的打斗場景中又由很多的物體組成,比如人、荒廢的車床、被嚇飛的白鴿等,這些就是游戲物體;廢棄的車床又由輪子、各個鋼鐵部件組成,這里的輪子和部件就是游戲物體的組件。換成 U3D 中的術語就如下圖所示:
以上就是 U3D 的簡要介紹,如果對 U3D 有興趣但自己又沒有基礎的,可以去 SiKi學院 上找免費的入門視頻來學習,想要看書的話可以去看看《Unity 5.X 從入門到精通》。
Unity3D 開發環境簡要說明
U3D 的開發工具叫 Unity 編輯器,在 下載地址 里選擇對應的版本和平台下的 Unity 編輯器即可,比如我這里選擇 Windows 平台的最新版本,如截圖所示:
U3D 目前只推薦使用 C# 作為腳本開發語言,為了方便編寫和調試代碼通常不直接使用 Unity 編輯器作為 IDE,我們使用 Microsoft Visual Studio(簡稱:VS)作為 C# 腳本的開發工具,可以點擊 下載鏈接 下載 VS,具體的安裝不再詳述。
安裝完成 VS 后,打開 Unity 編輯器,在菜單欄上選擇 Edit > Preferences…,在彈出的 Unity Preferences 對話框中選擇 External Tools > External Script Editor,最后選擇 VS 即可,如下圖所示:
到此為止開發環境配置完成。
基於 Unity 編輯器的測試框架介紹
NUnit.Framework 介紹
在 Unity 編輯器中已經集成了單元測試框架 NUnit,關於 NUnit 可以 點擊鏈接 了解更多,下面基於一個例子對它進行基本的介紹。
1 |
using UnityEngine; //基於 Unity 引擎,必須引用 |
以上是NUnit的一個例子,我們在 Unity 編輯器上執行看下效果。
可以看到,執行的情況就如代碼注釋里的說明一樣。通常,對於測試用例執行需要的必備條件的代碼可以寫在 OneTimeSetUp 里面,比如啟動測試環境;對於測試用例執行完最后需要的清理工作可以寫在 OneTimeTearDown 里面,比如退出測試環境;每個測試用例都需要初始化的公共代碼寫在 SetUp 里面;跑完每個測試用例都需要清理的公共代碼寫在 TearDown 里面。
Unity3D 單元測試的兩種模式
打開 Unity 編輯器,在菜單欄依次選擇 Window > Test Runner,在彈出的對話中可以看到 PlayMode 和 EditMode,這里的 Test Runner 對話框就是執行單元測試的 UI 界面,如果想進一步了解可以點擊 Test Runner 官網介紹 進行深入了解。又或者在 Project 視圖下依次執行 按下鼠標右鍵 > Create > Testing 也可以看到有 PlayMode 和 EditMode 字眼,下面是關於它兩的截圖。
EditMode 測試對於 Unity 編輯器而言,就是指在編輯狀態下去測試,而 PlayMode 測試對於 Unity 編輯器而言,就是指在 Unity 運行時的測試。我們可以這么理解,EditMode 是代碼的靜態測試,測試時不需要被測代碼跑起來,其實這里的 EditMode 就是跟其他編程語言的單元測試是一個意思;相對來說,PlayMode 就是代碼的動態測試,被測代碼需要跑起來,這時的代碼環境跟業務場景結合起來。
EditMode 測試模式
上文提到 EditMode 就是傳統意義上的單元測試,這里結合個例子介紹下。下面的代碼是被測代碼:
1 |
//被測代碼 |
在編寫 EditMode 模式的測試代碼時有一點需要注意下,測試代碼需要放在以 Editor 命名的文件夾下(子文件下也行,反正得在 Editor 下)才行,不然 Unity 編輯器無法識別。用例應該放在如下圖所示的地方:
然后編寫測試 BuildManager 對象的用例:
1 |
using UnityEngine; |
打開 Test Runner 對話框,選中測試用例 AddMoneyTest() 和 SubMoneyTest(),然后點擊 Run Selected 即可。如下圖所示:
PlayMode 測試模式
如果之前沒有創建過 PlayMode 模式下的測試用例,那么打開 Test Runner 對話框,並切換到 PlayMode 頁簽下,你會看到如下圖所示的提示:
然后點擊 Enable playmode tests 按鈕,再點擊 Enable 確定按鈕。
繼續點擊 OK 按鈕,接着點擊 Create Playmode Test with methods 按鈕,發現創建了一測試腳本:
1 |
using UnityEngine; |
這里重點介紹下 PlayMode 模式下測試用例的用法,如上代碼所示,其實 [test] 的注解就是普通的測試標簽,[UnityTest]標簽才是 PlayMode 測試用例的標簽,同時該注解下的函數返回類型是個迭代器 IEnumerator,我們注意到該函數內部還有一條語句 yield return null。其實還有類似的寫法,如 yield return new WaitForSeconds()、 yield return new WaitForEndOfFrame()、 yield return new WaitForFixedUpdate() 等。如果學過 Python 我們知道在函數內部中多了 yield 語句它就是生成器,生成器不會一下子返回可迭代對象的所有數據,而是每次返回一條數據,直至迭代完成數據。這里的 yield return 語句有點類似的意思。我們之前說過,PlayMode 測試模式是在代碼運行中去測試的,在 U3D 中運行的場景、物體或組件(代碼腳本也是一種組件)是每一幀每一幀持續去刷新的,可以把每一幀理解成一張圖片,隨着時間每一幀每一幀的刷新就形成了視頻動畫的效果。說回這里的 yield return的作用,它可以等待運行中的場景物體刷新一段時間(可以是等一幀、等一秒等)后再繼續執行下面的測試代碼。這樣的好處就是可以隨着時間(幀不斷刷新)來操作不同時期的場景、獲取不同時期的場景物體信息等,來實現模擬用戶或模擬場景的測試。
下面結合Demo來具體介紹下,先說說被系統:敵人(球)會在指定的路線下跑,跑到終點敵人就贏。玩家可以在指定的位置放置炮台,只要敵人走到攻擊范圍內,炮台就射擊。現在用 PlayMode 模式簡單測試下炮台的子彈是否會移動。下面是測試的代碼。
1 |
using UnityEngine; |
測試結果顯示測試通過:
好了,U3D的單元測試框架就先介紹到這里,后面結合實際的項目再做介紹。