本節書摘來自華章出版社《移動app測試實戰》一 書中的第2章,第2.1節,作者:邱鵬 陳吉 潘曉明,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
無論web網際網路的産品還是移動網際網路的産品都必須依賴大量的背景接口提供的服務,有很多的業務邏輯都是放在背景來處理的,是以非常有必要對這部分邏輯來做測試驗證。技術方案上,也可以模拟使用者的ui操作,從界面上發起相關的請求。但是實際中,會發現這樣的做法效率不高而且穩定性不夠,開發和維護的代價也比較大。針對這部分的測試,最直接的方式還是從接口層面發起請求來驗證。
就目前觀察,對于一些比較穩定的基礎性元件,比如底層平台、api、sdk等,或者功能通用性高的産品,比如防火牆、郵件系統等,都可以做到比較高的自動化率,而且自動化測試開發的方案也相對比較明确。相比而言,偏重應用層業務的測試團隊,通常在自動化方面的開展要困難很多,主要有以下幾個問題:
首要的問題是版本的節奏,網際網路産品版本節奏非常快,一個稍大的系統一周釋出上百個功能特性是一件很常見的事情。團隊成員有非常多的精力消耗在這些功能版本上,需要快速了解業務,建構測試環境,進行bug驗證回歸,以及釋出和線上驗證等,留給業務測試人員建構自動化用例的時間非常少。
自動化架構的開發代價比較大。自己開發或者維護過測試架構的人可能都深有體會,這絕不是一件容易的事情,其工作量和持續的時間往往會超出我們的預期,特别是對于大部分的網際網路測試團隊,尤其是一些初創團隊。而另一方面,也很難找到一個現成的,能滿足特定需求的平台。
實際的項目,特别是大型的項目,功能通常都非常的複雜,需要将業務邏輯通過架構的能力來表達,對建構用例來說也存在一定的門檻。而測試開發人員由于對各個業務細節的了解程度不夠且精力有限,對于需要建構大規模自動化測試用例的系統也是一個挑戰。
對于一些大的網際網路研發團隊,如果有一個比較大的測試部門,對應有比較強的測試開發能力,可以考慮自己開發一套自動化測試架構,然後可以在多個業務測試團隊複用。對于一些人力有限的團隊,則需要考慮一些輕量級的方式。這裡不準備介紹如何開發一個自動化架構,那可能需要寫一本書的篇幅。下面将要介紹的是适合小團隊的一些測試自動化的方法,基于我們之前在一些實際項目中的實踐。這套方法我們曾在幾個不同類型的項目中得到應用,包括電商的後端erp系統、web網站以及app的背景接口,都獲得了比較好的實際效果,同時測試開發和用例編寫的代價相對可以承受。
這個輕量級方法的核心是采用開源測試工具jmeter作為引擎,把發送接口請求,以及結果的解析和斷言的工作都交給jmeter的基礎功能來實作。這樣的考慮涉及兩個問題:一是為什麼不從頭開發一套完整的自動化架構?二是為什麼采用jmeter?
關于不從頭開發一套完整的架構,主要的考慮如下:
1)首先主要是開發成本的考慮。用目前任何一個主流的開發語言,比如java/python/php等,寫一個協定層面的收發都非常簡單,因為有了大量的通用的庫。但是如果用于自動化測試,需要考慮的方面非常多,比如以http協定為例:
需要考慮資料編碼的問題
需要處理連接配接的建立,銷毀的問題
需要考慮cookie的問題,自動重定向的問題,是否用keep-alive
對于post,需要處理發送前的資料準備問題
需要處理代理的問題
需要處理傳回資料的解析
需要支援各種斷言的形式
2)在自動化測試的開展過程中,會不斷對底層架構提出新的要求,需要有持續的測試開發人力投入。
3)需要保證架構的高品質和穩定性。很多内部開發的架構都會遇到上面的問題,投入了大量人力,開發了很長時間,也需要持續的維護,但是一旦有大的産品和人員的變動,很多時候,架構或者架構的很多功能都會被廢棄。
4)這可能不是團隊的工作核心。開發一個http等基礎協定的收發處理的架構對很多業務測試團隊來說,都不是核心的職責和最重要的事情,特别是人力有限的情況下。
基于這樣的考慮,為了快速建構一套可用的自動化架構,我們決定尋找一個開源的工具,能完成協定層面的基本功能。最後我們選用了jmeter,基于它來建構我們的自動化平台。
jmeter是apache software foundation下面的一個開源項目,有超過10年的曆史了。它是一個純java編寫的測試工具,最早主要用于http協定性能測試(現在這仍是其主要用途之一),但是後來随着功能的逐漸豐富完善,它也成為一個接口協定測試工具,以及自動化測試工具。下面介紹下它的一些特點,主要從功能測試的角度,其他更進一步的資訊可以參考它的官方文檔,或者下載下傳之後試驗。
支援多種不同類型的協定
從圖2-1可以看出,jmeter自帶支援的接口協定有多種,可以直接應用,省去了上面提到的接口協定的資料收發方面的開發。
對http協定的支援比較全面
http是網際網路最常用的協定,目前很多移動網際網路産品也是通過http協定來完成背景的互動。jmeter對http的支援比較全面,如圖2-2所示,對于協定方法、請求的參數和選項、代理等方面都提供了支援。

除此之外,還提供了cookie管理、cache管理、消息頭和授權管理等輔助功能,如圖2-3所示。
3.其他非直接支援的協定可以通過擴充方式實作
某些實際項目中,可能在app和服務端通信上采用非上述标準協定之外的其他協定,包括一些私有協定。對于這種情況,可以通過jmeter提供的通用元件來編寫代碼擴充,或者更進一步編寫jmeter插件,類似于一個新的sampler。接下來我們通過一個例子看看如何通過現有元件來擴充。
對于其他私有通信協定的接口,我們可以通過jmeter的os process sampler來進行橋接和測試,如圖2-4所示。os process sampler可以用來啟動一個可執行程式,由于是通過指令行方式啟動,是以我們可以用任何語言編寫一個測試用的可執行程式。在該可執行程式中調用我們的接口,調用完成後可以做簡單的解析判斷輸出文本資訊,也可以把傳回的原始資料輸出而交由jmeter做後續解析判斷。具體做法是往該程序的标準輸出流寫入資料。之後在jmeter 中即可讀取這些資料。
以c#語言為例,在測試程式中我們可以用下列代碼輸出文本到标準輸出流:
var res=prev.getresponsedataasstring();
var haserr=res.contains("[!error!]");
if(haserr)
{
//這裡可以增加斷言或者進行變量指派等常用操作
}<code>`</code>
通過上述例子可以看到,測試用可執行檔案的輸出與jmeter的輸入資料需要有一定的約定格式。該資料格式在項目中可以根據實際情況自由設計。
支援豐富的斷言
對于接口測試而言,斷言是一個非常重要的功能,而且實際項目中,可能需要比較複雜的斷言方式來判斷結果是否正确。
圖2-6所示是jmeter提供的響應斷言,可以看出,其支援的檢查内容比較多,包括響應代碼、響應頭和body内容等方面,檢查方式也支援多種不同的規則。
支援内嵌自定義腳本
實際中,一個功能的自動化可能需要多個步驟,包含調用多個接口來完成。而多個接口之間有一些邏輯管理,比如後面的接口依賴前面接口的響應資料,甚至資料需要做一些處理才能為後面的接口所用。針對這種情況,可以通過jmeter内嵌支援的自定義腳本來實作,可以使用javascript和java等語言。
下面我們以javascript語言為例,通過一個實際的例子來看看,如圖2-7所示。
這個例子是針對一個電商app的首頁樓層布局的檢查,前面的接口傳回了各個樓層的資訊,這裡的bsf postprocessor裡面的js腳本以前面接口的傳回作為參數,解析出其中各個樓層的資訊,然後存入到數組中。之後後續的接口就可以讀取這些變量,逐個地通路這些樓層的資訊。
可以直連db檢查資料
在實際的接口自動化中,除了通過接口層面來檢查執行結果,有些不能在接口中傳回的,或者接口中資訊比較少的,也可以通過直接查詢db的方式來檢查資料和結果。在jmeter中可以通過jdbc request這個sampler來實作。圖2-8所示是一個具體的例子。
可以直接在其中編寫sql腳本來通路對應db中的資料,擷取到資料後可以存入變量做進一步的斷言和處理。
可以嵌入執行第三方指令行
可以使用os process sampler和beanshell sampler來執行一些外部的指令、使用者環境和資料的準備等功能。
文本的輸入和輸出
jmeter的輸入和輸出都是文本的形式,包括界面編輯的配置存成jmx文本,需要的測試資料也可以通過文本的方式提供,另外,執行之後的結果也是存成文本的。這樣的方式,友善了後續其他腳本的處理和結果的解析。
圖形界面和指令行啟動執行
jmeter本身提供圖形界面,極大地友善了用例制作和調試,不但提供請求配置和腳本編寫的界面,也可以用于執行和調試,并有對應的多種形式的報告,讓用例制作和調試的過程變得簡單。當調試完成後,可以用指令行的方式來執行jmeter腳本,而不需要打開gui,也友善自動化架構的封裝。
工具本身非常穩定
最後一點也是一個很重要的方面,因為自動化會比較頻繁的執行,而且可能執行的時間比較長,是以工具和架構本身的穩定性也非常重要。jmeter作為一個開源工具,有非常廣泛的使用者基礎,得到過比較充分的驗證。新版本也在持續開發中,是以穩定性和可維護性方面比較有保障。
還有更多細節的功能這裡不一一介紹了,有了上述這些特性後,就可以用于接口自動化的建構了。如果獨自開發上面提到的這些功能,并在實際使用中穩定下來需要花費比較大的代價。借助已有的開源工作,圍繞其做二次開發,是下面的自動化方案可以做到比較輕量級的主要原因。
有了上面這些基本的功能,接下來需要考慮如何整合成一套完整的方案,包括考慮用例的可複用和可擴充。
實踐中我們的基本思路如下:
用例的分層
為了更好的複用和管理,我們對用例的層次進行一些劃分,并給出名稱的定義。單次接口請求是一個最小粒度的操作,比如下面示例中的一次http請求,在以下我們稱之為cgi。cgi這個詞的本意是通用網關接口,由于習慣的原因,常常用來代稱單個業務接口。function是一個對外有邏輯意義的請求組合,比如送出訂單、稽核訂單。testcase是一個成品,testsuite是一個用例的集合。基本的組織方式如圖2-9所示。
通過這樣的分層,整體邏輯就比較清楚了,cgi對于一個具體的接口是最小粒度的元素,如果接口變化了,隻需要修改對應的cgi用例。function層面是一個有邏輯意義的功能,可能需要多個cgi共同完成,相當于做了一層封裝,為後面建構用例打下基礎。
每個子系統的目錄結構如圖2-10所示。
這裡有個需要注意的小地方,為了部署的時候更靈活,希望腳本中互相引用的檔案是相對的路徑,但是jmeter支援不太好,預設的根目錄是bin,是以簡單的做法是把整個自動化用例的目錄複制到jmeter的bin下面。
2.完整的自動化用例結構
因為我們有多個系統,對應多個測試小組,大家各有專注,而整個業務又是一個長鍊條。function層就是我們複用的基礎,裡面包含了對cgi層接口的調用。注意一點,jmeter 2.10開始建議用testfragment來組織,而testfragment是不能直接執行的,隻是些積木,到了testcase層面再用threadgroup線程組才可以執行。圖2-11是一個test fragment的示例。
圖2-12所示是一個完整的testcase,包含了本系統和其他系統的一些function步驟。
實際多人協作的過程彙總,用例細節有很多需要規範的地方,比如命名規範,這樣便于多人協作。
資料的輸出
jmeter裡面配置和編寫用例執行完了之後,需要拿到輸出的結果,外層的自動化架構才能進行解析和結果的輸出。這裡我們通過添加一個“察看結果樹”的監聽器,将所有的執行結果輸出到一個文本檔案裡面,如圖2-13所示。為了解析友善,通過變量指定了一個确定的檔案名,資料結果方面選擇了所有的列,便于得到完整的結果并處理。
自動化的報告
基于上述步驟輸出的文本結果,可以編寫一個解析器,把結果解析成比較易于閱讀的方式。然後生成對應的報告,每次執行完成之後自動地發郵件報告出來。圖2-14是一個自動化測試報告的例子。
用例執行細節查詢
除了上面彙總之後的結果報告,還需要一個地方能看到用例執行的細節,幫助定位問題。實際中我們建構了一個web平台,測試人員可以在上面看到每次測試的結果,以及每個用例的執行細節。
為了更好地定位問題,需要把每個接口執行的細節也暴露出來,點選詳情可以看到調用的情況,包括request和response的資料,如圖2-15所示。
到這裡為止,一個比較完整的可以在實際項目中應用的自動化架構就完成了。在實際的運作過程中,可以對業務測試人員進行一些jmeter方面的教育訓練,讓大家熟悉如何構造接口的請求,以及斷言處理等子產品,然後就可以編寫對應的用例了。當然,如果多個人來準備測試用例,也需要知道哪些cgi和function級别的封裝是已有的,可以複用。
可見,除了jmeter以外的架構部分的開發工作外,工作量不是很大,很多較小規模的測試團隊也可以承受。綜合來看,基于這樣的方案可以快速地把一個可用的自動化系統建構起來。
上述方案在一個項目中實踐的情況如下:
1)覆寫了4個大的系統,200多個cgi接口,以及100多個功能點。每個系統在建構後快速地通過以上自動化用例來進行回歸,并發出郵件報告,架構整體比較穩定。
2)整個過程,不算制作用例的時間,我們實際投入的測試開發的人力約為一個人/月。
3)大部分業務測試人員都參與到了用例的制作,提升了對業務邏輯的了解,并且對部分人員來說,也學習了http協定等基礎知識,并編寫了少量的腳本,提升了業務測試人員的自動化和測試開發能力。
總體來說,達到了輕量化來建構接口自動化的目标。
除了以上好處,也有一些不友善的地方需要指出:
jmeter在包含其他的jmx腳本後,不能直接在界面顯示加載的内容,是以看不到被包含的腳本裡面的步驟,調試的時候不友善。不過jmeter可以支援多個執行個體同時運作,是以在編寫和調試階段,可以同時打開多個jmeter視窗,一定程度上可以緩解這個問題。
最後的測試報告裡面,不能控制顯示結果的層次,是直接展開成每個接口的結果,當用例的步驟過多時檢視起來不是特别友善。
除了技術層面的考慮,自動化執行的過程中還有幾個建議值得考慮:
1)一定要強挂鈎到測試和釋出的環節。這一點看起來沒那麼重要,但是如果不希望自動化測試成為花瓶,必須要這樣做。網際網路産品的節奏非常快,如果自動化不能實際地在項目中發揮效果,就很容易被荒廢。目前來看最合适的點是在每次自動部署後快速地把自動化用例執行一遍,這要在手工測試開始之前。這也是持續內建的思路,可以快速地發揮自動化的價值。
2)報告也需要自動化地發出來,并且郵件抄送給相關的開發人員、測試人員和團隊負責人。這樣可以讓大家快速地關注到結果。
3)非100%成功的都要跟進。甯願少而精,就像“破窗理論”指出的,如果能容忍一個用例失敗,就會有2個、3個,也會讓自動化慢慢失去意義。我們的做法是隻要有失敗,對應系統的測試負責人員需要進行定位并郵件回複出問題原因和處理措施。
4)需要關注用例的細節。測試團隊的負責人需要去關注用例的品質,而不隻是用例的數量和執行情況,比如斷言做到什麼程度,哪些自動化資料是寫死的,哪些參數化了,功能之間的複用情況,這些都是影響整個自動化的穩定性和可維護性的具體方面。