申明一下,只是在這里拋磚引玉,各位如果有好的方法和建議,歡迎指正。
首先,據我了解,國內的游戲(MMORPG)行業(國外的我不知道哈),幾乎還沒有比較成功的游戲自動化測試體系,或許是我孤陋寡聞吧!有少數公司在做,但是效果都不很明顯,結合我自己的做的一些經歷和實際操作,小小的說說自己的想法。
1.目前市面上的一些測試工具如:lr,wr,qtp什么的不適合做游戲自動化測試,至少我沒找到合適方法。個人理解是因為這個工具實際是通過簡單錄制或定制一些行為來實現自動化測試的,做游戲自動化測試,這些工具有幾個重大缺點:
部署成本高:
自動化體系在server端很難部署,定制行為的時候幾乎不能調用到游戲的接口,無法獲得游戲實際運行的信息,預期結果不方便定制。如果是通過簡單錄制回放的話,效率不如手動操作好,對一些繁瑣的行為,幾乎是不現實的,而且這些工具對tcp/ip協議支持不如http協議好,有興趣的同學可以去研究研究。
效果差強人意:
我之前用lr做了一下游戲自動化,不到一周我就放棄了,后來招了一個lr的新人,我在百般勸說下,他都沒放棄游戲lr的自動化測試,結果3天不到,他也放棄了!游戲自動化測試本質目的是提高測試效率,用lr反而降低了測試效率,那么我們還用lr來干什么呢?這里我也不多說原因了,到后面我會提一下另一種方法的,主要說另一種方法的優勢,而這種方法的優勢恰好是這些工具的劣勢。
2.幾乎所有的游戲在前期架構設計上就沒考慮到游戲自動化測試的需求,所以在游戲后期介入自動化測試幾乎是不現實的。
3.公司沒有足夠的人力物力,或者說項目組就沒有意識到自動化測試的意義,所以也無法開展。
4.測試自身的能力,很多(現在不是幾乎了,有的游戲公司的測試還是很nb的)測試自身能力不足,或者接觸不到游戲代碼或其他需求無法滿足,導致無法進行自動化測試。
這一篇,我主要說說游戲自動化測試對游戲架構的需求:
首先,如果在一款成熟運營的游戲中,試圖讓測試自動化起來,幾乎是不大現實的。原因不外有二:
1.我要想在游戲世界里刷出一個怪或要取得一個player的信息,如果我們的開發人員沒有暴露接口出來,請問,我們該怎么辦?
2.我們要做一個自動化體系,是我們自己再去開發一個新的系統呢?還是用原來的系統?如果開發一個新系統,那么我可以告訴你,國內幾乎沒有那個項目老大允許你這么做,運營期的游戲,最重要是一個持續穩定,如果你插入你的開發量進去,我可以明確的告訴你,你會完全打亂你老大的計划。那好,那我們在原來的系統上改吧?對這一點,我相信有經驗的同學都知道,去改別人的代碼的效率遠遠低於自己開發的效率(如果是小改動,可能是達不到自動化的效果的)。
這2個原因是阻礙游戲自動化的主要因素,當然還有其他因素,比如對項目組對測試認識方面等等的問題,這些我不在這里討論,這里只說說技術上的需求。
在項目風格基本確定后,就是程序架構的設計了,如果在這個時候不考慮到測試的一些需求的話,那后期做起來就會很難。
一般來說,游戲設計分3大塊:1.數據庫設計;2游戲邏輯server;3 游戲的邏輯client。這里的server是廣義的server,不同公司的設計是不一樣的,不細分。游戲client就是指平時我們運行的,可以實際“玩”的游戲,運行在我們玩家的pc機上的可執行程序。
對於我們測試來說,其實可以把數據庫獨立出來,數據庫和游戲的交互無非就是存取修改操作。在不考慮的性能情況下,自動化測試可以不考慮數據庫,當然對於數據安全性等的操作其實屬於策略問題。
其實我們實際做的自動化測試主要是游戲server的實際運行和與client的交互。這里再強調一下,自動化的本質是為了提高測試效率,所以我們只讓計算機做他適合做的事情,而不是把所有的測試都交給計算機,那可能就本末倒置了,反而是為了自動化而自動化,沒意義。
設計上要求務必達到:
(1)低耦合,高內聚
這個能簡化我們實現測試的過程,又能讓我們更准確的定位問題和回歸問題。具體原因這里就不說了,可以去看看軟件設計和測試的一些資料。
(2)游戲運行要高透明,游戲運行的對象是可以給定條件獲得,並且運行條件是可編輯的。
這個問題不能太深入,太深入可能公司就要找我麻煩了哈,大家原諒一下。這樣設計的目的就是為了,我們可以定制我們的測試過程和預期結果。
(3)通信是是可以設置和編輯的。
其實client與server的交互的本質是通過發送數據包來實現的。我們游戲人員通常說的協議其實是制的一個一個的數據結構,而不是tcp/ip之類的協議。實現這個的目的是我們在部署大量client與server交互的時候不需要運行我們的client,只需要一個發包client就可以了,而不需要弄上幾千幾萬個物理client。
(4)所有的接口在發布版本是關閉的。
這個是鑒於某公司之前出現了一次嚴重事故而增加的,之前某公司由於發布失誤,導致外網玩家可以直接編輯游戲運行的一些數據,這個做起來也非常簡單,在server上加一個宏就可以實現:ifdef _Debug define Test endif 就可以了。在編譯發布版本的時候,就不會暴露這些高危數據出來,當然方式有很多,根據自己情況定是最好的。
前面我大概說了一下游戲自動化測試的一些現狀需求,這一篇主要談談游戲里面哪些可以做,哪些好做,哪些難做,哪些沒必要做以及一些原因。歡迎拍磚哈,希望大家也談談你們的做法和優點。
我們在做游戲自動化測試之前,我們先假設我們的架構已經設計的足夠好,允許我們能夠通過我們的測試工具,獲取游戲的運行狀態並且修改游戲的狀態。原本打算寫到五就差不多了,后來應一些朋友的要求,我會大概說說游戲架構沒有考慮到自動化測試的時候,自動化測試可以做的一些事情。
據我了解的情況,目前國內所有的網絡游戲都是采用面向對象的方法設計和實現的,如果有不是的,我沒接觸過,也不知道用什么辦法去做,所以再一次假設,我們的游戲都是使用的面向對象的方法設計和實現的,請記住,這里我再三提到對象這個概念。后面講的一些東西將會圍繞這個概念展開。
還是先說一下哪些東西不建議采用自動化測試吧:
1.表現類,以主觀感受為主為測試目的測試對象。
大家都知道,計算機最喜歡做的是邏輯性計算,而不是人性計算。之所以不做,原因就是這類測試幾乎無法定義預期結果,所以更不要談測試結果了,如果沒有測試結果,那么計算機做了什么呢?這種問題主要集中在client上,比如畫面,音效,操作性,當然還有設計的游戲平衡性等等。這里標准其實就是:當人無法用邏輯語言表達出預期結果的東西,不要試圖自動化。
2.性價比低,一次性勞動且開發量大的測試對象。
自動化的目的是為了提高效率,而不是為了自動化而自動化,也不是為了來表演某個人的技術能力。我見過某公司的一個朋友,曾經花了幾大天的時間做了一個測試工具,僅僅是為了節省一個人半天工作量的測試工作。這種主要是需要做一個評估:這個測試工作是經常的嗎?這個的自動化測試的開發成本是多少?我以前才開始做的時候,一個同事給我提了一個需求,讓我單獨給他做一個工具,用來檢查策划新提的一個數據文件,這個數據文件只是他們的一個設計文件,而且文件內數據的關系只是有這個策划的心情來決定的,我當時傻不拉嘰的給她做了(我估計我當時是色迷心竅)。而我花2天做的東西,她就點了一下鼠標,從此以后這個東西就永久的存儲在工具庫里了,不知道何年何月這個工具才能重見天日。因為我不知道將來是否有一天,還會有策划會按這個規則去設計他們的數據表。說明一下,這類數據文件之間的關系完全是通過數據來對應,一旦對應關系發生改變,測試代碼也需要改變,所以重用性不高,而且這個僅僅是他們拍腦袋的結果,並不是我們實際運行在游戲中的數據文件。
說了這么多,現在開始說哪寫東西適合做自動化測試:
計算機喜歡干重復性邏輯活動,那我們就讓他干這種事情吧。
簡單算一下效率,假設某個測試工作需要5人*2小時/天的工作量,而且每天都是重復的工作,比如我們做游戲的,一般游戲發布前都需要對版本質量進行review,這個事情如果我們可以在我們下班后,讓計算機去做,會是多么幸福的一件事情啊!假設游戲生命期3年,每周發布一次版本,每次發布前需要10個小時的絕對工作量,那么3年就是10*52*3/7=223,也就是要花費一個人223天的工作量,這其實是一個人一年的工作量了,而我們開發這個東西只需要10天!
我們做自動化測試的時候,一般做通用性的東西,也可以叫做平台類的工具,在這個平台上,我們再設計自己的行為,通過這個平台作用於游戲,再通過平台將結果返回給我們的測試代碼。
而這個平台就要回歸到前面所說的對象概念了,我們運行在游戲種的一些邏輯其實都是一些對象的行為。結合我們的測試可以說其實我們測試就是側某一個對象在某一個狀態下,是否產生了某種行為和沒有產生不應該的行為。有了這個概念,我們設計自動化測試思路就清晰了。
首先,這個平台我在二里面沒提出這個說法,但是其實就是這個概念。這個平台主要是實現:實現測試代碼和游戲的通信,通過這個平台,我們測試代碼可以獲得和修改游戲運行的環境。
這個平台是長期維護的,當游戲一些邏輯發生變化的時候,平台可能需要相應的變化,否則可能會阻礙測試。平台是通用的,測試代碼是針對具體的測試對象而設計的。
我們假設現在需要測試一個任務(下列是我將這個任務分解了一下,為條件和步驟哈):
1.找a npc能接取到 a1任務。
2.找其他npc不能接到a1任務。
3.角色等級>=10級。
4.角色有道具b。
5.角色pk值大於5.
6.扣除b道具后,角色接得a1任務。
7.角色殺20個怪后,可以交任務。
8.任務不能重復做。
接下來,我大概說說測試思路哈:
player = GetPlayerByName('xxx') 首先獲得一個player對象,這里前面就是談到的對象概念了。
player.SetLevel(10) 設置player對象等級
player.AddItem(b,n) 設置角色身上道具b
player.SetPkValue(5) 設置pk值
player.ChangePos(x,y,z) 將player傳送到npc那
player.GetMenu(npc,choice) 選擇和npc對話和具體選項。
if player.GetItemNum(b)!=n-1 or player.task[taskid].status:判斷是否正確接到任務和扣除道具
Error(player) 如果錯誤,則返回player的數據(包含任務等數據)
return false
好了,這里說個思路就是了,我們實現自動化測試的思路大概就是這樣的。當然其實這個還可以進一步做的,相信大家見過一些地圖編輯器和任務編輯器,我現在可以說一個,其實我們自動化測試的時候可以做測試編輯器。思路還是和上面說的一樣。
只是要做這個測試編輯器,就需要更好的設計優化我們的測試平台,將我們測試行為分離成指令+數據的形式。比如上面說的找npc對話接任務,我們平台可以設計一個接口:GetNpcOption(npcid,choice,player)實現把player傳送到npcid那並選擇某個選項。這個接口首先需要能找到這個npcid的npc,然后吧player傳送到這里來,然后player選擇這個choice。好了,我們假設我們這個也已經做過優化了。接下來,我們設計用例吧:
操作過程
player.level=10
player.SetItem(b,n)
player.pkValue=5
GetNpcOption(npcid,choice,player)
預期結果:
測試結果就拿來和預期結果比較就可以了。相信這樣說大家已經明白了這個測試編輯器怎么做了,就是將我們行為和數據簡化成指令+數據,我們可以通過這個編輯器來編輯測試行為,而我們的測試平台需要能解釋這些行為。這里測試平台要吧這些行為翻譯成游戲能理解的數據。這個最初我以為開發量會很大,但實際做下來,這個翻譯行為比預想的輕松得多(當然,前提還是架構充分考慮到這些問題哈)。
好了,我們現在可以把精力充分花在設計用例上了,我們可以把最擅長設計用例的人充分利用起來,讓少部分人去維護吧,這樣,我們就可以把最合適的人放到最合適的崗位上去了。
為了測試更全面,我們還可以更進一步,讓我們測試編輯器,可以設計一些隨機行為,這里隨機行為一個是數據的隨機,一個是操作順序和操作的隨機(前提是這些操作隨機后是游戲平台能識別並翻譯的)。我們還可以定義只要不滿足什么條件就是測試不通過的。這樣只要我們的測試覆蓋率就直接受我們設計測試影響了。一些人無法實現的大量,重復的,偶然的也可以做了。
一些朋友問我:能不能再具體點?其實已經很具體了,自動化是一種思想,就像lr,qtp一樣,其實工具並不重要,關鍵是你的思路,有了思路,一切就都有頭緒了。當然有的東西可能不適合你們。畢竟不同公司條件或做法都有區別。