為什么又一篇自動化測試的文章
如果搜索自動化測試相關(guān)的文章,看到的集中在兩類:一是宏觀上的關(guān)于手工測試和自動化測試的區(qū)別、自動化測試的優(yōu)缺點、測試金字塔應(yīng)該的結(jié)構(gòu)(比如三角、倒三角、甜筒、梯形、洋蔥、地球儀模型等),等等。一是微觀上的關(guān)于測試工具的使用。對于讀者來講,在沒有一定的實踐基礎(chǔ)上,前者很容易陷入一種形而上的討論,讀時不明覺厲,掩卷不知從哪開始。后一種又很容易造成一種“自動化測試=自動化工具/自動化執(zhí)行”的錯覺,弄不好便會變成拿著錘子找釘子。
本篇文章的嘗試回答這樣的問題:如果QA沒有太多自動化測試實踐,但又在測試效率上碰到瓶頸,冀望自動化測試就能解決當前困境時,應(yīng)該作出怎樣的一些思考?。(注:文章后半部分會涉及HTTP接口,希望讀者已經(jīng)了解HTTP協(xié)議的基本內(nèi)容)
從頭講起 - 測試的cycle time
測試的核心問題是:測什么(What),怎么測(How)。對QA來講,測試就變成要能夠想到、還要能夠測到(測試效率)。這兩個問題有時有本質(zhì)的困難,有些測試點就是再給出兩倍的時間也不一定能想到,同時有些測試能想到卻不一定能測到(比如全組合測試)。
在這種理解上,自動化測試到底能幫助QA什么呢?要說清這個問題,還得先從基本的測試過程開始。一般一次完整的測試要經(jīng)歷以下步驟:
理解需求、測試分析、設(shè)計用例、準備環(huán)境、準備數(shù)據(jù)、執(zhí)行用例、判斷結(jié)果、(報Bug、重測)、Sign off
如果說測試是QA對質(zhì)量的反饋,并稱呼從“理解需求”到“Sign off”為一個完整的測試Cycle,那么可以說只有經(jīng)歷了一個完整Cycle的測試才更有意義。比如,設(shè)計很多用例而不執(zhí)行,團隊并沒有從“設(shè)計用例”活動中得到有效的質(zhì)量反饋(除了一些澄清)。同樣,有了Bug而不報告,也不能算有效的測試,因為真實的質(zhì)量反饋并沒傳達到團隊。
另外一方面,可以簡單定義從“理解需求”到“Sign off”所經(jīng)歷的時間為測試Cycle Time,那么如果Cycle Time過長,長到團隊得到第一次反饋時已經(jīng)是迭代Last Minute,這時也可以認為測試效率很低。這也包括對Bug的重測過程。
自動化測試的目標應(yīng)該是測試Cycle Time的整體的縮短,加快測試反饋周期。

要理解這個,可以借助價值流圖的方式,給以上每個步驟記錄一個時間,我們能得到這樣一個結(jié)果:
假設(shè)單個階段活動為5分鐘,且只有一個Bug并一次修復成功,則測試Cycle Time合計5*8 = 40分鐘。如上圖,QA要經(jīng)歷30分鐘(不含Bug時間)的測試活動才能給團隊第一次的測試結(jié)果,經(jīng)歷40分鐘的測試活動才能將相關(guān)功能Sign off.
如果“自動化測試=自動化執(zhí)行”,哪怕把執(zhí)行時間縮短為秒級別,Cycle Time也只減少了5分鐘,節(jié)省5/40 = 12%的時間。
但是如果我們的自動化節(jié)省了包括準備環(huán)境、數(shù)據(jù)等的時間,比如用基于模型的方法自動化了分析到準備數(shù)據(jù)的全過程,使其整體時間縮短到5分鐘,則節(jié)省的時間則是20-5 = 15分鐘,節(jié)省15/40 = 37.5%的時間。
糟糕的自動化是有了很快的執(zhí)行速度,卻給“喂”了無效甚至錯誤的測試數(shù)據(jù),這時的執(zhí)行快只是一種假象,無助于加快有效反饋的目的。還有一種自動化測試是將手工測試用例翻譯成自動化測試腳本,這通常只是片面追求執(zhí)行快而已,整體Cycle Time也許變得更長,因為書寫和維護自動化腳本也是要花時間的。
自動化測試工具的出發(fā)點

當我們執(zhí)行了數(shù)個測試用例,也就是經(jīng)歷了數(shù)個測試Cycle后,發(fā)現(xiàn)一些活動可以抽象出來,如上圖所示,這也就是一大類工具產(chǎn)生的根源。也正因為如此,大多數(shù)工具都是為了某類特殊目的而產(chǎn)生,同時天生就有其局限性。據(jù)不完全統(tǒng)計,目前的測試工具數(shù)以百計,并且還在增加中。諸多工具中,很大部分都聚焦在用例執(zhí)行上。
測試工具作為基礎(chǔ)設(shè)施,輔助QA測試,但是在“測什么”這個問題上收效甚微,還得依靠QA自身的分析能力。QA需要明確自己的測試問題域,同時理解這些工具的設(shè)計出發(fā)點,合理地使用它們。從Cycle Time的描述可以看出,只著眼測試執(zhí)行的工具通常離Cycle Time整體縮短的目標還有相當大的距離。
所以當你碰到瓶頸,以為是因為沒有使用某個或某類自動化工具時,請仔細想想你的測試問題域和已有的測試過程是否已經(jīng)優(yōu)化了。通常我們會發(fā)現(xiàn),優(yōu)化現(xiàn)有的測試過程比單純增加一個測試工具的效果更突出。
注:考慮QA的日常,可以再細分一下,以便參考:
常規(guī)用例設(shè)計與執(zhí)行
探索用例設(shè)計與執(zhí)行
回歸用例設(shè)計與執(zhí)行
其它非功能性用例設(shè)計與執(zhí)行
以API自動化測試為例
上面講的都還在概念層次,我們以API測試為例來具化一下這些概念,來看看測試、自動化測試、測試工具的聯(lián)系,以及一個新測試工具的產(chǎn)生過程。
聚焦在API上,一方面很多系統(tǒng)的對外服務(wù)本身就以API為主。另一方面,隨著架構(gòu)的演進,大多網(wǎng)站也采用了前后端分離的方式,也就是API對外可見,相當于系統(tǒng)給用戶暴露了至少兩類訪問途徑。據(jù)說douban,facebook等網(wǎng)站的API直接訪問量是大于其Web訪問的。
API測不測?如果系統(tǒng)只提供API服務(wù),答案是肯定的。但是如果系統(tǒng)是網(wǎng)站或者系統(tǒng)有前端界面,得到的答案卻有點“模糊”,一方面QA受本身技術(shù)的限制沒有意識到API的存在及其重要性,另一方面以前端界面為默認或者承諾的交互方式為由而降低了它的優(yōu)先級。但是如果以用戶可能會通過什么樣的方式來影響系統(tǒng)的角度上講,只要API有訪問的可能,API測試覆蓋就不可或缺。
API測試場景 - 測試問題域
API作為專門測試,除非有專門工具的封裝,它沒有Web那樣直觀的界面,需要對相應(yīng)協(xié)議的理解。要想談API自動化測試,就得先看看QA測試API時有哪些場景以及難點(先假設(shè)我們只討論功能和性能,不涉及安全、契約測試等)。
場景1:單個API的單次執(zhí)行,只要會至少一種API調(diào)用方式即可,比如curl、Postman之于RESTful類API。(難點:無)
場景2:單個API的多次執(zhí)行,這時需要對API的正常返回、異常返回以及API對多種數(shù)據(jù)組合進行測試。(難點:大量數(shù)據(jù)的準備和管理,測試執(zhí)行)
比如:對一個POST請求,Post body有6個字符串類型字段,如果一個字符串正向、負向數(shù)據(jù)合計為5,則全組合為5的6次方:15625
場景3:多個API的單次執(zhí)行,它們之間沒有依賴。(難點:管理每個API以及它們對應(yīng)的數(shù)據(jù))
場景4:多個API的單次執(zhí)行,它們之間有執(zhí)行順序依賴,沒有數(shù)據(jù)依賴。(難點:管理API間的執(zhí)行順序)
場景5:多個API的單次執(zhí)行,它們之間有執(zhí)行順序依賴,也有數(shù)據(jù)依賴。(難點:管理API間的執(zhí)行順序,數(shù)據(jù)依賴)
場景6:多個API的多次執(zhí)行,它們之間有執(zhí)行順序依賴,也有數(shù)據(jù)依賴。(難點:管理API間的執(zhí)行順序,數(shù)據(jù)依賴,大量數(shù)據(jù)的準備和管理,測試執(zhí)行)
通常,一個系統(tǒng)開發(fā)到中期時(比如4個迭代),系統(tǒng)可能會累計超過30個API,它們會包含GET、POST,數(shù)據(jù)依賴。同時QA需要時時對系統(tǒng)回歸,以及通過API對系統(tǒng)數(shù)據(jù)準備等,并持續(xù)這些活動到開發(fā)結(jié)束。大一點的系統(tǒng)超過100個API也不少見。
場景7:API的數(shù)據(jù)來源于第三方系統(tǒng)(難點:數(shù)據(jù)源不可控)
場景7的項目上下文依賴太多,暫時不予討論。其它6個場景卻可以很明確地識別其難點。從量級上講,假設(shè)系統(tǒng)有50個API,平均每個API需要準備和執(zhí)行正向、負向數(shù)據(jù)組合為50,則我們有50*50 = 2500個用例。管理這個量級的數(shù)據(jù)和執(zhí)行并不是一件容易的事。
API自動化測試的方向
從上面的分析可以看出,2500個測試用例的執(zhí)行和管理是一個很大的挑戰(zhàn)(國內(nèi)項目通常只有一個QA,而API測試只是QA在項目中眾多的測試活動中的一種)。這就是QA面對的問題的特殊性,因為開發(fā)通常不會面對這種規(guī)模的用例管理與執(zhí)行。這時必然要通過某種途徑縮短Cycle Time,使完成每次測試周期的代價足夠小,我們要從分析到執(zhí)行到報告等各個環(huán)節(jié)上下功夫。
首先,API測試有天然的Data-Driven的特點,一條數(shù)據(jù)就是一個用例,并可以直接執(zhí)行(嗯,沒有中間環(huán)節(jié)賺點擊)。
同時,準備這些數(shù)據(jù)已經(jīng)有很多方法論及其工具的支持,比如組合測試,等。
在CI/CD成為標配的今天,測試環(huán)境一般不成為問題,除非有大量的第三方依賴。
但執(zhí)行效率有時卻成為關(guān)鍵,如果平均一個API執(zhí)行時間為1秒,串行執(zhí)行2500個用例則需要2500秒,約42分鐘。如果并行執(zhí)行,則需要考慮場景、優(yōu)先級及依賴。
考慮到對整個產(chǎn)品的所有API進行管理和執(zhí)行,碰到的難點就包括但不限于:管理單個API的測試數(shù)據(jù)以及各類數(shù)據(jù)變種、執(zhí)行和報告,多個API的數(shù)據(jù)、執(zhí)行和報告,API的依賴,按場景執(zhí)行,按優(yōu)先級執(zhí)行,并行執(zhí)行,統(tǒng)計結(jié)果、性能數(shù)據(jù)。
通過測試流程改進并不能解決上述的所有問題,這時引入自動化就成為必然。市面上API測試工具很多,這些工具在協(xié)議層做到了盡善盡美,同時也提供比較方便的界面。但是面對QA碰到的上述特殊性要求卻總顯得力有不逮。以幾種工具或方式為例:
Postman:用戶界面友好,易上手,但API數(shù)量和測試數(shù)據(jù)變多后,管理就很不方便
SoapUI:老牌API測試工具,支持Groovy script對Test Case的定義和管理,對QA有代碼要求,與工具強綁定
Programing(比如Java Junit + httpclient,Python pytest,等):對QA的代碼要求高,實施周期長
我們還有什么選擇
既然已有的方案和工具不能解決問題,而QA碰到的問題又那么實實在在,也就只有嘗試自己梳理方案甚至寫新的工具了。這里有兩個方向:
一:只解決當前項目的問題,方案與項目上下文強相關(guān)。好處是沒有多余工作,缺點是方案可移植性差。
二:抽象上面的問題,得到通用方案或者工具。好處是多個項目可重用,但是需要大量的基礎(chǔ)性工作,針對特定項目還要在通用方案或工具上輔以針對性的手段。
仔細梳理了上述問題域,根據(jù)方向二,經(jīng)過一段時間的努力,工具Go4Api已經(jīng)初見雛形:
— Go4Api定義了一種精簡的Json格式,自我表達,它包含一個用例、用例間關(guān)系和HTTP Request/Response/Assertion等全部信息,同時本身還可以參數(shù)化,由另外的數(shù)據(jù)文件驅(qū)動。
— 借助Go語言并發(fā)內(nèi)置的語言特性,Go4Api的調(diào)度機制能處理成千上萬的用例以及管理它們的優(yōu)先級、先后依賴、數(shù)據(jù)依賴、并發(fā)執(zhí)行。
— 面對API測試里多種數(shù)據(jù)組合問題,Go4Api內(nèi)置了Mutation Test和Fuzz Test。其中Mutation Test功能能對現(xiàn)有的數(shù)據(jù)進行多種Mutation(即正、反向變異)并執(zhí)行;Fuzz Test能根據(jù)API及其Fields的定義,通過規(guī)則生成數(shù)據(jù),并實現(xiàn)了Go語言版的Pairwise算法,對用例數(shù)進行有效降低并執(zhí)行。
— Go4Api還可以對HAR、Swagger API的格式文件進行轉(zhuǎn)化,使之成為Go4Api能識別并處理Json格式。


更多詳情請見Github地址:https://github.com/zpsean/go4api
wiki: https://github.com/zpsean/go4api/wiki
go4api能做什么,不能做什么
Go4Api解決了之前所列場景1~場景6所識別出來的所有問題了嗎?還不徹底。比如以下兩點沒有完全支持:
— 如果一個API的數(shù)據(jù)來源于多個API的執(zhí)行結(jié)果,這種復雜的數(shù)據(jù)依賴部分支持。
— 一個POST API創(chuàng)建了新的數(shù)據(jù),可以通過go4api Scenario功能為它加一個包含DELETE API的Child Case達到 tear down的目的,但是如果系統(tǒng)還沒有DELETE API呢?傳統(tǒng)的方法是SQL Delete等方式,Go4Api目前部分支持sql形式的teardown。

另外,Go4Api有圖形操作界面嗎?目前沒有看到有界面的必要。但是Go4Api提供了友好的可視化測試報告。
總結(jié)
測試是一個系統(tǒng)活動,是否自動化測試以及怎樣自動化測試需要全面考慮測試的問題域本身。
自動化執(zhí)行不等于自動化測試,縮短測試Cycle Time,加快測試反饋周期應(yīng)該是考慮自動化測試方向的重要因素。在有些場景下,自動化測試數(shù)據(jù)準備可能比自動化執(zhí)行帶來更多好處。
測試工具不是天生的、也不是萬能的,它通常是針對某類測試問題域的解決方案。如果使用不當,誤把工具當測試問題,只會練就屠龍術(shù)而已,無助于解決測試問題本身。
注:作為驗證,Go4Api已經(jīng)在作者參與的項目實際使用。后續(xù)會有文章介紹Go4Api具體的應(yīng)用場景和實際使用經(jīng)驗,敬請期待。
另外,為啥預覽顯示很好的小圖片發(fā)布后變那么大,width調(diào)整不生效。-_-!!