那天,自從我把Unity升級到2018後,我重新想起了無法做單元測試的恐懼…
前言
Unity有個功能叫TestRunner,可以讓你寫代碼來測試代碼。
好處就是節省代碼時間,如果一段程式要用十種方法來反覆測試,用手動測試光是想到Debug就頭皮發麻,但改成使用TestRunner不過就是手指點兩下的功夫
筆者在做編譯器時的TestRunner列表
但有個很大的缺點是需要人機互動或太過複雜的功能就很難在上面測試。
例如:玩家按滑鼠左鍵對亂數移動的敵人施放火球術是否能命中目標並扣除200滴血+10秒灼傷效果
因此這項功能的主要用途是檢測輸入A是否回傳B
這種基本邏輯。
那能出什麼亂子呢?
回想那天我心血來潮把5.x版的Unity升級到2018,結果TestRunner裡的測試案例卻消失了。
蝦毀Σ(゚д゚)
嗯,沒關係,程式還好好的待在資料夾裡,只是UI看不見而已,新的版本嘛,可能改了路徑之類的東西吧?大不了重新開一個新的測試案例然後再把舊的程式Copy過去不就得了嗎?
總之咱先姑且弄個新的TestRunner試試看
using System.Collections; using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; namespace Tests { public class Test { // A Test behaves as an ordinary method [Test] public void TestSimplePasses() { // Use the Assert class to test conditions } // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use // `yield return null;` to skip a frame. [UnityTest] public IEnumerator TestWithEnumeratorPasses() { // Use the Assert class to test conditions. // Use yield to skip a frame. yield return null; } } }
很輕鬆就打開了Unity創建的測試範例,到這裡為止都沒啥問題
public class Foo { public bool GetBool() { return true; } public int GetInt() { return 0; } }
接著我們寫了一個測試測試案例的測試碼
然後貼到Test裡面……我了個去,不存在Σ(゚д゚)!?這麼會睜眼說瞎話幹什麼工程師啊,去當政府官員啊!
搗鼓了大半天後,終於發現問題的題示在Visual Studio的方案總管上
上圖可以發現Foo跟Test在不同的方案內,而且因為Unity的限制我們也無法讓Tests方案去參考Assembly_CSharp方案。網上試了查了各種資料始終沒有任何方法可以毫無副作用的讓Tests方案參考到Assembly_CSharp方案。
但看似無解的謎團最後在我契而不捨的追查下終於看到了一線曙光!
破局
解鈴還需繫鈴人,BUG隨時逼瘋人。
首先第一步,咱先Assets
裡建一個Editor
然後在Editor
內建一個Test
資料夾。
這邊簡單介紹一下Editor資料夾
Editor跟Resources資料夾一樣都是Unity的保留資料夾
Editor資料夾內主要放使用了UnityEditor函式的程式
該資料夾的內容在輸出時將不會被打包進去
接著點開Test資料夾然後打開TestRunner
點選Create Test Script in current folder
最後打開剛剛創立的測試腳本就能看到測試腳本被放入了Assembly-CSharp-Editor
方案內
而且之前的Foo
類別也被正確參考到了!
在TestRunner視窗內點兩下證明測試案例是可執行的。
參考
想更清楚的知道TestRunner的使用方式可以前往下列文章
透過 Unity測試工具(Unity Test Tools)來進行快速的測試
該文提到的NSubstitute已失聯,可以到我的google硬碟中下載
將Dll檔放入Editor內即可使用