1. 程式人生 > >從0開發3D引擎(四):搭建測試環境

從0開發3D引擎(四):搭建測試環境

目錄

  • 上一篇博文
  • 瞭解自動化測試
    • 單元測試
    • 整合測試
    • 端對端測試
    • 通過列印日誌來除錯
  • 瞭解執行測試
    • 斷點除錯
    • 通過Spector.js測試WebGL
    • 通過log除錯Shader
    • 移動端測試
  • 瞭解效能測試
    • 測試時間開銷
    • 測試記憶體開銷
  • 搭建本地測試環境

大家好,本文介紹了3D引擎的測試方法,搭建了本地的測試環境。

上一篇博文

從0開發3D引擎(三):搭建開發環境

瞭解自動化測試

對於引擎開發這種複雜、長期的專案,為了減少bug,提升長期的開發效率,自動化測試必不可少。在我們的Wonder.js引擎中,包括了本節介紹的3種自動化測試,測試覆蓋率達到了95%。

本系列為了節省篇幅,不進行自動化測試。因此本節只進行簡單的介紹,不給出實際的案例,讀者可以到Wonder.js->test/目錄下檢視自動化測試例項。

單元測試

我們需要寫測試用例對單個函式進行單元測試。

搭建環境
使用jest作為測試框架,sinon進行stub。
如果讀者想了解stub的概念,可以參考我對Stub和Mock的理解

因為不能直接使用js庫,需要寫對應的FFI(類似於typescript的d.ts檔案)才能在Reason中被呼叫,所以我們可以使用bs-jest和Wonder的Wonder-bs-sinon作為FFI

整合測試

相對於單元測試,整合測試的測試目標變為某個特性,該特性跨越多個函式或多個模組。

搭建環境
與單元測試的環境一樣。

目錄結構
可以在test/unit/目錄下寫單元測試用例,而在test/integration/目錄下寫整合測試用例。

端對端測試

也稱為e2e測試,包括了“渲染測試”和“效能測試”。它們都需要安裝puppeteer,通過chrome核心渲染3D場景來進行測試。

  • 渲染測試

渲染測試是針對特定的場景(如只有一個模型的場景,或者只有一個光源的場景)進行測試,從而保證渲染的正確性。

測試步驟為:
1、預先渲染一張正確圖片
2、使用引擎渲染一張當前圖片
3、逐個畫素地比較兩者,如果95%以上的畫素都相同,則測試通過;否則測試失敗

  • 效能測試

效能測試是針對極端場景(如5000個box)進行測試,從而保證花費的時間和佔用的記憶體大小符合要求。

測試步驟為:
1、預先準備基準資料
使用引擎執行場景多次,取平均值,記錄到json檔案中
2、使用引擎執行場景多次(少於“準備基準資料”的執行次數),取平均值,得到當前資料
3、比較兩者的花費的時間和佔用的記憶體大小,如果在誤差範圍內,則測試通過;否則測試失敗

注意事項:
只有在本地測試時,保持基準資料不變。如果在雲端(如在push到Github倉庫時使用CI工具-travis進行測試)或者其它環境(如換一臺電腦進行測試)進行效能測試,需要在每次測試時更新基準資料(因為不同的環境,效能不一樣,所以對應的基準資料也不一樣)。

通過列印日誌來除錯

有以下的原因使得可以在單元測試和整合測試中通過列印日誌來進行除錯:

  • 因為在自動化測試中開啟watch,程式碼修改後能夠立即重新整理,所以能夠即時看到列印的結果,測試很方便
  • 因為在函數語言程式設計中,函式為純函式(Reason也允許非純),沒有狀態,所以我們可以通過列印函式的輸入和輸出,來驗證該函式是否正確

瞭解執行測試

本系列通過在Chrome瀏覽器中進行執行測試來驗證程式的正確性。

通過以下的方式進行執行測試:

斷點除錯

因為瀏覽器執行的是Reason編譯後的js程式碼,所以我們可以在瀏覽器的控制檯->Sources中通過斷點來除錯js程式碼

具體可以參考:
使用斷點暫停程式碼

通過Spector.js測試WebGL

Spector.js除錯預覽:

Spector.js能檢視一幀中WebGL的呼叫情況、shader程式碼和WebGL的狀態,它支援WebGL 1.0或WebGL 2.0,也支援WebGL 1.0的VAO等擴充套件。

另外,Spector.js支援多個canvas,能檢視指定的canvas對應的WebGL資訊。這對於除錯編輯器(如我們的Wonder-Editor線上編輯器)很有用。因為編輯器有多個canvas(如一個canvas進行主場景繪製,另一個canvas以材質球的方式顯示單個material資產的效果),而我們希望分別除錯從每個canvas中取得上下文的WebGL。

Spector.js可以在Chrome的擴充套件中安裝,詳情請見官方Github

通過log除錯Shader

本系列通過在fragment shader中,將變數作為輸出的顏色,來除錯Shader的變數值。

更多可以參考:

除錯OpenGL -> 除錯著色器輸出

OpenGL shader如何除錯?

OpenGL ES 2.0 Shader 除錯新思路(一): 改變提問方式

移動端測試

我們通過下面兩種方法進行測試:

  • 模擬測試

我們可以在Chrome瀏覽器上,點選控制檯->Toggle Device Toolbar,開啟用於模擬移動裝置視口的介面。

本系列主要用該方法測試引擎對於移動端touch事件的支援。

詳細的介紹參考:
使用 Chrome DevTools 中的 Device Mode 模擬移動裝置

  • 真機測試

具體步驟如下:
1、在測試html頁面中引入vConsole庫
從而可以通過列印日誌的方式,在手機上檢視錯誤和日誌資訊
vConsole介紹參考:
前端開發 - 在手機上除錯利器vConsole
2、把測試頁面push到測試環境的伺服器上(如使用Github Pages搭建的伺服器)
3、把測試頁面的訪問地址轉換為二維碼
如使用草料二維碼線上轉換
4、用測試手機的微信掃該二維碼,執行測試頁面,驗證渲染結果,檢視錯誤和日誌資訊

瞭解效能測試

因為本系列開發的引擎重視效能,所以會通過手動的效能測試,來指導引擎優化。

效能測試的指標包括時間開銷和記憶體開銷,下面分別分析:

測試時間開銷

  • 使用Chrome DevTools的Javascript Profiler

通過在測試頁面記錄profile,檢視每個函式的時間開銷,從而定位到熱點函式進行優化。

相關資料可參考:
加速執行 JavaScript
Chrome DevTools 之 Profiles,深度效能優化必備

  • 使用Chrome DevTools的Performance

通過時間線Timeline,可以檢視CPU端各個執行緒和GPU的執行順序和熱點函式的時間開銷。

本系列主要用該方法測試在多執行緒中,每個執行緒的執行順序和效能開銷

相關資料可參考:
如何使用 Timeline 工具
Chrome DevTools 之 Timeline,快捷效能優化工具

  • 使用Chrome DevTools的NetWork

檢視各個資源的載入時間和順序。

本系列用該方法測試在“使用函式式反應式程式設計的流來非同步載入 js、二進位制檔案等資源”時,各個資源的載入順序是否正確。

  • 使用Performance.now

使用該方法列印某段邏輯的時間開銷,多用於自動化測試->端對端測試—>效能測試。

本系列在使用profile定位到熱點函式後,會使用該方法確定具體程式碼的時間開銷。通過比較優化前和優化後的時間開銷,來評估優化的效果。

示例程式碼為:

var n1 = performance.now();

執行某些邏輯


var n2 = performance.now();

//列印邏輯的時間開銷(ms為單位)
console.log(n2 - n1);
  • 使用Console.profile

相對於Chrome DevTools的Javascript Profiler,該方法可以測試某一段邏輯的profile,而不是整個頁面的profile,粒度更小,更加可控。


(圖來自Chrome 控制檯console的用法(學了之後對於除錯js可是大大有用的哦))

測試記憶體開銷

  • 使用Chrome DevTools的Memory

本系列對這個工具的應用:
使用Allocation sampling,定位記憶體佔用的熱點函式;
使用Allocation instrumentation on timeline來比較每一幀記憶體開銷的增長情況,從而確定是否有記憶體洩漏。如果有記憶體洩漏,則通過Heap snapshot,記錄多個記憶體快照並進行比較,定位到具體是哪些地方增加了記憶體。

相關資料可參考:
解決記憶體問題

搭建本地測試環境

執行測試和效能測試不僅需要使用Chrome瀏覽器的控制檯功能,還需要:
1、安裝Spector.js
Spector.js可以在Chrome的擴充套件中安裝
2、進行移動端測試時,需要在測試頁面中引入vConsole庫,並使用Github Pages搭建測試服