前言
現在流行的測試驅動有數據驅動,行為驅動,關鍵字驅動。初聽,甚是高大上,不明其理。車子講究兩驅四驅前驅后驅等,根據路況或場景來選擇不同的車子,測試也搞驅動?那么這三個流行的驅動方式,到底哪一個才是人間真理?如何選擇?別急,百曉生帶你一探究竟。
什么是驅動?
什么是驅動?驅動什么?車子上的驅動,是指發動機的布置方式,顯然是為了驅動車子跑動起來,所以車子上的驅動,只是一種布置架構,同理,測試中的驅動,是指測試框架的架構,是為了驅動測試腳本的執行。車子最重要的是能跑動,測試腳本最重要的是能夠被執行,所以,驅動就是執行!
數據驅動
數據驅動(Data Driven),這里強調的是數據,驅動即執行,那么數據驅動就是根據數據來執行測試腳本。
場景:測試登錄,分別用劉能和趙四的帳號去測試。
先寫一個公共方法來描述登錄的過程:(偽代碼實現)
public boolean login(String username, String password){ //do login }
再到測試方法里面去調用這個login方法/函數:
public void test1(){ login("liuneng","123456"); } public void test2(){ login("zhaosi","654321"); }
這樣測試用例就寫完了,執行test1與test2兩個方法即可。但細心的你可能會發現test1與test2這兩個測試方法里的方法體除了數據,其它完全一樣,這就存在重構的空間了:
public boolean login(String[][] accounts){ for(int i = 0; i<accounts.length; i++){ //do login } } public void test(){ String[][] accounts = [["liuneng","123456"],["zhaosi","654321"]]; login(accounts); }
經過重構后的代碼,就有點數據驅動的意思了,根據accounts的length來決定login方法/函數體運行幾次,這樣維護起來就方便了,假如又有一個老王的帳號想用來測試,就不需要再加一個測試方法了,只需要:
String[][] accounts = [["liuneng","123456"],["zhaosi","654321"],["laowang","000000"]];
重構后的代碼,是不是令你很激動?原來這就是數據驅動!別急,淡定,這還不是真的數據驅動,因為上面只有一個測試方法,最后執行完后,報告中記錄的也是只有一個測試方法,而場景中:分別用劉能和趙四的帳號去測試,是希望在測試報告中有兩個測試方法出現,顯然上面的代碼還不能滿足我們的需求,於是進一步優化:
public boolean login(String username, String password){ //do login } public void test(String username, String password){ login(username,password); } public void executor(){ String[][] accounts = [["liuneng","123456"],["zhaosi","654321"]]; for(int i = 0; i<accounts.length; i++){ test(accounts[i][0],accounts[i][1]); } }
是的,離數據驅動原理真相越來越近了,上面多了個executor方法,這是啥?這就是車子的發動機引擎啊,就是測試腳本的執行引擎,讓測試方法能夠被執行起來,以及根據你所提供的測試數據的條數,決定測試方法的執行次數,並且報告中會顯示是兩個測試方法,這就是數據驅動。測試框架就是一個執行引擎,並且測試框架都會支持數據驅動這一基本訴求,比如testNg里的dataProvider,junit里的Parameters等。大家可以下去查一下自已所使用的測試框架的數據驅動寫法,然后就可以重構優化自已的腳本啦!
行為驅動
數據驅動強調數據,行為驅動(Behavior Driven)當然得強調行為了。那么問題來了:什么是行為?需要注意的是,手工測試人員中或產品人員,很多都是不懂代碼的,或者說他們壓根不想去關注你這個腳本是如何實現的,他們更關注這個腳本覆蓋了哪些場景,而通過代碼或者注釋告訴他們腳本的實現場景顯然是不現實的,於是尋找一種大家都能夠看的懂的"通用語言"來描述腳本就顯得很重要了,偉大的計算機學者們把這種"通用語言"的描述定義為行為,這就是行為驅動的由來,即通過"通用語言"來執行腳本。
場景:測試購物流程。
先用一種"通用語言"來描述這個場景(這是一個單獨的文件,命名為shop.feature):
步驟1:進入'華為P9'手機產品頁並點擊加入購物車按鈕 步驟2:在購物車頁面點擊結算按鈕
上面的行為描述不管是手工測試人員,還是產品人員都能看懂,除非他不懂漢語。行為定義好后,他們爽了,能看懂了,但腳本人員卻傻了,如何把這些行為描述與腳本聯系起來?別急嘛,有了理論基礎,代碼實現豈不是分分鍾!
def /進入'華為P9'手機產品頁並點擊加入購物車按鈕/ //coding, doing something end def /在購物車頁面點擊結算按鈕/ //coding, doing something end def executor() lines = read('shop.feature') for line in lines Method m = searchMethod(line) //通過正則並根據步驟內容來找到方法 m.run()//對line進行解析,比如''里面的代表參數,執行找到的方法 end end
只要是驅動,都會有執行引擎,所以上面的示例中也有一個executor方法來執行行為描述文件。行為驅動的原理就是循環讀取並解析事先寫好的行為描述特征文件,特征文件中的每一步都用一些特定符號或者特定字符串來標識參數,對象等,以便在解析時能夠根據這些特定的符號或字符串來獲取相應的值,當有了這些值以后,再根據正則來找到對應的方法並執行即可。行為驅動的好處就是把行為描述文件與實際的腳本進行了分離,特征文件給不懂代碼的人看,腳本給開發人員看並且維護。行為驅動的作用及實現原理就是這樣,現在也有很多很好的行為驅動測試框架,比如java里的JBehave,ruby里的cucumber,rspec等,至於行為驅動的好處與壞處,請期待百曉生后續文章,精彩持續不斷!
關鍵字驅動
關鍵字驅動,就是把代碼映射成關鍵字。可能有人會說,行為驅動的行為描述文件也可以理解成關鍵字,通過關鍵字來查找到對應的方法並且執行,那行為驅動與關鍵字驅動的不同點在哪?其實個人認為也就是一個描述文件的定義先后順序問題,行為驅動是先定義描述文件,然后產品人員與手工測試人員審核通過后,腳本開發人員再去根據描述文件來代碼實現,而關鍵字驅動,是腳本開發人員先去寫好代碼,然后把代碼方法的關鍵字給定義后,然后再給產品人員與手工測試人員審核,你要說這兩個驅動哪個好哪個壞,難分伯仲,只有符合自已公司業務特點的驅動才是好驅動。百曉生以前的文章里有一篇<<關鍵字驅動的原理和實現>>,大家可以自行查閱,也是干貨喲!
總結
目前市面上的測試驅動的工具或者框架,都有一個共同點,就是都支持數據驅動,所以數據驅動才是根本之王。深入了解並熟悉數據驅動,結合測試框架,打造出符合公司業務特點的自動化測試框架,從此走上人生巔峰,當上CEO,迎娶白富美!最重要的一點:請持續關注百曉生!
百曉生微信公眾號二維碼:

