一個項目越到後期越能感覺到自動化測試的重要性, 如果早期能把這塊做好, 可以少踩很多坑...

From Wiki:

《盜賊之海》是一款以海盜作為主題的第一人稱視角多人合作動作冒險遊戲[1][2]。遊戲支持Windows個人電腦和Xbox One電子遊戲機之間跨平台遊玩[3]。一群玩家將會通過海盜船環遊並探索開放世界,同時進行不同的任務,比如船隻駕駛或者使用大炮作戰[2][4]。玩家可以完成任務、收集戰利品或進攻其他玩家[4]。《盜賊之海》是個公共的遊戲世界,也就是說玩家們在冒險中可能會遇見對方[2]。遊戲有著卡通式畫風以及誇張的物理引擎,允許玩家進行特技動作,比如用船上的大炮把自己射出去[3][5]。

主要內容:

  • 為什麼搞自動化測試
  • 怎麼搞自動化測試
  • 怎麼在開發過程中改進
  • 搞了四年自動化測試帶來什麼好處

(做分享的套路一, 開場先說挑戰, 反正有多難說多難)

  • 開放世界->高複雜度->Bug無處不在
  • 網路遊戲->持續改進->不斷增加新玩法->新特性破壞老特性->Bug頻出->影響玩家體驗
  • 快速響應玩家反饋->版本周期超短->沒有足夠的時間驗證功能->沒有信心扔給玩家玩

(做分享的套路二, 丟出一個傳統方案(人工測試), 反正有多爛說多爛)

人工測試的問題: , 不靠譜

(話說好像我見過的項目都是這麼搞的, 難道是人力成本太低了...)

舉了個AI在轉角出Bug的例子來說為什麼人工測試不靠譜, 因為如果開發者和測試者在流程中很容易只關注功能特性本身的正確性, 而忽略了它與周邊模塊的相關性測試, 這樣的Bug就會伴隨著版本發布, 然後等過了幾星期後玩家問候了自己的親人才知道去改, 這時候開發者都不知道是哪些提交導致的問題了, 好不容易改了Bug後還可能產生新的問題來重複這個循環...

(做分享的套路三, 提出自己的方案, 通過對比體驗優勢)

  • 人工測試可以很快地完成這個AI的功能測試, 但是不可能把所有的場景都覆蓋一遍
    • 自動化測試可以解放測試者的人力
    • 自動化測試比人工測試跑得快
    • 自動化測試可以進行更精確的檢測
    • 自動化測試可以針對不同場景甚至函數進行測試, 而人只能跑完整遊戲
  • 自動化測試也不是萬能的
    • 人工測試更擅長發現視覺和聽覺的問題
    • 人工測試能做探索性的測試發現新的問題
    • 只有人才能測試遊戲的玩起來的體驗怎麼樣

所以機械性的測試讓自動化測試來跑... 那人工測試跑啥呢?

交代完背景, 開始進入正題

基於UE4的AutomationSystem修改而來, 可以整合進日常構建流程中. 開者發寫完代碼跑一遍, 立碼就有信心提交了, 再也不用擔驚受怕了

單元測試大家都長得差不多, Setup->Run->Check

集成測試用來覆蓋遊戲中的一個特性或行為, 多個單元測試之間可以做一些通信

  • 如果其中一個單元出錯, 顯然錯誤就在那兒
  • 如果所有單元測試通過, 但是集成測試失敗了, 就需要花點時間查查, 但是也可以把範圍縮小到某個特性上

集成測試都做成了一個個的地圖, 使用Blueprint來組裝節點執行

比如測試船的舵輪旋轉, 不用開個客戶端, 弄個測試地圖, 只有一個平台, 一個玩家, 一個舵輪, 沒了

之所以沒有放船, 那是因為需要排除不必要的干擾, 船舵方向算是另一個測試了

Blueprint也是分成那三步來執行, Assert節點測試沒通過會輸出Log, 這個測試就會被標記成失敗了

Unreal Automation窗口結果一目了然

  • 如果是當前幀不能立即驗證的, 可以藉助Delay節點延遲檢查
  • 盡量避免寫死一些固定的值, 比如強依賴某個動作播放的時間
  • 如果條件一直不滿足的話, 設置Timeout強制失敗

網路測試咋做呢?

  • 集成測試可以在伺服器上跑, 也可以多個客戶端跑
  • 開發過程中可以在Editor里跑虛擬伺服器和多個客戶端進程
  • 典型的網路集成測試
    • 伺服器啟動測試
    • 切換到客戶端1, 檢查網路通信
    • 切回伺服器
    • 切換到客戶端2, 檢查網路同步結果
    • 按需求重複流程
    • 切回伺服器結束測試

比如這個多個玩家交互的測試:

  • 玩家1跟轉動舵輪
  • 舵輪狀態通過網路發到伺服器
  • 伺服器同步舵輪狀態到另一個客戶端, 這時進行角度的正確性檢查

SyncClientServer會自動啟動客戶端並且跟伺服器做好握手

通過一個Blueprint把網路測試的整個流程給串了起來, 很方便

除了單元測試和集成測試, 還有些別的測試類型:

  • 資源審核 (原來我們還針對這個批量資源規範檢查開發過功能, 原來還能用自動化測試搞)
  • 截圖測試, 跟參考圖對比差異百分比檢測畫面的問題
  • 性能測試 (這個很有用, 一定要在項目早期就搞)
  • 啟動流程測試, 保證版本能跑

(實際開發過遊戲項目就知道如果有這些測試會省多少時間, 然而並沒有幾個項目會去搞......)

  • 自動化測試是構建系統流程中的一部分
  • 如果測試失敗, 圍繞團隊的屏幕會變紅, 提交的人的名字會顯示在上面
  • 只有測試通過的提交才會合入, 免得影響其他人(想想很多人連編譯通不過就提交了...)
  • 只有代碼的修改才會需要進行覆蓋測試, 美術和策劃的提交已經包含在資源審核測試里了
  • 沒有專門的測試工程師, 誰開發的功能誰來寫測試
  • 每次提交只做有限的相關測試, 不然很影響開發效率

完整的流程是這樣的:

  • 開發者先預提交, 構建系統會進行相關的自動化測試, 通過後才會合入
  • 通過類似"性能測試"的方式及時暴露問題, 有時候的提交會被移除, 保證版本質量
  • 通過了自動化測試的版本才會進行人工測試
  • 最後一關是外網的內測玩家反饋

(分享的套路四, 自己挖的坑自己填, 體現技術深度)

自動化測試提升版本穩定性的同時, 也帶來了不小的負擔:

  • Creation Time: 需要時間來寫測試用例, 這樣冒似降低了特性的開發速度
  • Running Time: 自動化測試的組合拉長構建流程, 開者發提交後要排隊等半天才知道自動化測試的結果有沒有通過
  • Unreliability: 沒有哪個自動化測試的組合可以保證完美覆蓋所有問題的, 所以開發者需要花時間不斷完善測試用例, 導致測試越來越複雜, 花的時間越來越長

(反正問題很多, 後面就說怎麼填坑了)

自動化測試的幾個層次, 越往上依賴越多, 時間越長, 越不可靠. 上層的正確性是建立在下層穩定的基礎上, 使用Unreal引擎的類, Unreal的地圖等會造成依賴的功能模擬過多, 所以考慮把玩法測試移動到更底層的位置減少依賴

使用Actor類來做測試, ActorTest處於集成測試和單元測試的中間層次

比如這個根據光照變換形態的骷髏, 在ActorTest中做更方便

ActorTest寫起很很像單元測試, 但是背後複雜, 比如創建了個場景, 設置了時間, 更新了邏輯等. 好處是執行起來比集成測試快得多.

這就需要在集成測試和ActorTest之間做一些平衡, 比如前者用來測試正確的遊戲情景(Golden Path), 後者用來測試邊界或失敗條件. 比如一個玩家交給另一個玩家道具的例子:

  • ActorTest用來檢查失敗條件, 集成測試用來檢查交付成功
  • 通常兩者的數量比例是12:1

只對"Golden Path"應用集成測試, 大大減少了他們的數量, 那執行時間怎麼優化呢?

那就是在一個集成測試中, 執行多個相關特性的測試, 這樣雖然打破了一個測試只測一個特性的規則, 但是減少執行時間更重要(開始自己打自己臉...)

很多測試中都會有玩家角色, 但是載入和初始化角色是相當耗時的, 比測試本身執行的時間長多了, 所以可以利用Unreal的World Transition特性, 把角色從一個測試場景轉移到另一個測試場景. 比如上圖第一個測試是控制舵輪, 第二個測試是控制絞盤, 角色是共享的, 只需要注意不要把玩家狀態從一個測試帶到另一個測試中去.

有一些測試失敗是偶現的:

  • 比如硬體設施問題, 網路問題, 狀態泄露(從上一個測試帶過來的)等. 雖然會停下工作花時間去查, 但是對於查這些非功能性上的問題比較浪費時間
  • 所以在測試失敗發生時, 會立即重複執行一次, 同一個測試只有連續失敗兩次, 這次構建才會被標記成紅色, 這就減少了一些對開發工作的打斷次數

忽略偶現的問題並不是代表不去管它了, 失敗的次數會被統計下來, 出現次數最多的肯定值得找人去專門查一下

  • 有些測試如果老是失敗又改不好, 那說明寫的有問題, 不如直接刪掉, 省得浪費構建時間和查錯的人力成本
  • 如果一個測試在一段時間內一直失敗, 它就會被隔離, 省得因為一直測試不通過影響大家提交. 負責這個測試的工程師需要在第一時間去修復這個問題, 不修的話這個測試會自動被刪除
  • 如果一個問題沒有在及時被修復, 那說明他不重要, 不應該出現構建系統里

(分享套路五, 開始吹自己方案的好處了, 壞處上面都當成坑填了, 深坑是不會告訴你的)

  • 70%是ActorTest, 遊戲玩法的測試這個是最實用的
  • 5%是集成測試, 屬於更上層的覆蓋測試, 比如網路同步相關的問題
  • 截圖/性能/啟動測試非常少, 因為他們太慢了, 一般單獨拿出來跑
  • 最終這些類似所有測試加起有23212個, 還有81700個資源檢查測試(真嚴格...)

好處一: 減少了驗證構建版本的時間, 上個遊戲要花兩星期, 這個項目才1.5天. 這樣可以非常有信心地發布給玩家, 快速收集反饋, 大大加快了迭代速度

好處二: 減少了人工測試的數量, 上個項目50個, 這個項目才17個, 而且玩法複雜度不是一個量級的(省錢是省錢了, 我還沒見過哪個項目會請50個測試的...)

好處三: 減少了Bug數量. 相對於另一個項目3000個的量級(嗯, 又換了一個對比對象, 肯定這個項目Bug比Kinect Sports Rivals多...), 這個項目才214個. 因為自動化測試強制通過才能提交合入, 很多Bug在進入版本前就被修復了

好處四: 降低了項目的時間壓力, 對比另一個項目, 加班變少了 (功勞當然是自動化測試的). 做項目的都知道一出版本就會加班, Bug數量決定加班時間

(分享套路六: 開始上升到非技術層面, 談談哲學, 講講教訓, 當前提是前面不能講砸了)

  • 很多團隊不做自動化測試是因為比較花時間, 但是他們不知道能省下多少時間(回頭想想做過的項目, 一聲嘆息...)
  • 不要低估寫好測試花的時間, 包括搭建這套系統和跑通整個流程. 先在項目里一個模塊加入自動測試是一個比較容易落地的方式.
  • 自動化測試對於迭代玩法樂趣開發時是一個干擾, 做這些原型時會單獨開個沒有自動化測試的分支.
  • 自動化測試需要不斷改進, 再也不用在小本本上記下需要測試的內容了. 測試需要集中在容易出Bug的地方, 避免那些需要花大量時間維護的複雜測試. 完美的測試理論上可能, 工程上不可能達成.

講完還不忘了打廣告, 那我寫完也打個廣告吧:

NEXT Studios神秘項目招聘資深工程師, 這裡有個早期視頻和一些概念設計:

視頻封面

01:35
  • 工作地點: 深圳
  • 遊戲平台: PC/Console, 有機會嘗試一些手游上現階段做不了的技術
  • 遊戲類型: 反正不是強化升星的, 做完可以把名字寫進Credits
  • 工作職責: 就是負責技術選型落地, 帶領團隊實現一段夢幻世界的遊戲體驗

有意向的私信或發簡歷到xoyojank@qq.com


推薦閱讀:
相关文章