此文已由做者翟曜受權網易雲社區發佈。
html
歡迎訪問網易雲社區,瞭解更多網易技術產品運營經驗。java
mock測試常見的定義爲:在測試過程當中,對於某些不易構造或不易獲取的對象,經過建立虛擬對象的方式來模擬測試的測試方法。算法
提到mock測試工具,java領域內可能首先想到的是Jmock、EasyMock、JMockit等。一般在單元測試中,因爲對象、方法不是獨立的,測試代碼難以構造,因此業界提出了Mock Object技術來孤立被測試的對象。以上幾種Mock 框架都限於一個Mock概念:即Mock Object 是用來代替與代碼協做的對象的對象。和這幾種框架同樣,其餘的 mock 框架也基本都侷限於單元測試範疇,而在集成測試功能測試階段尚未相應成熟的框架進行支持。因此本文提到的mock測試,更確切來講,是在功能測試階段解決如何與外部系統間的數據交互。安全
文章結合本人所在的項目【秀品】來作相關介紹。大多用戶直接接觸到的只是秀品商城,但實際整個秀品業務系統的運轉比較複雜,其中便涉及到和多個外部系統的對接及數據交互,好比倉儲和物流都會和EMS、順豐等有數據交互。而最近秀品開始涉及跨境業務,相應和電子口岸、境外的物流商等又會有數據交互。服務器
固然,跟外部系統對接時系統間的聯調測試必不可少,有些外部系統提供測試環境,有些甚至不提供。即使是提供測試環境的外部系統,通常也僅在開發聯調階段配合提供聯調測試對接服務,一旦聯調測試結束,也再也不繼續提供測試服務。那麼,當這些外部系統的聯調測試環境不可用時,咱們就需模擬這些外部系統來和秀品系統進行數據交互,以便支持秀品完整業務測試流程的正常進行。針對這類mock測試需求,秀品QA作了幾種實踐,也是在實踐中總結再改進的過程。app
秀品系統採用的通訊協議主要有:dubbo協議和http協議。和外部系統對接都是採用http協議,因此目前只需模擬外部系統對秀品系統的http請求回調功能。框架
以秀品和EMS(倉儲物流商)的WMS(倉庫管理系統)交互爲例,EMS會提供一份標準對外接口文檔給秀品。不一樣業務接口的調用形式和接口參數基本是一致的,僅經過參數值傳遞與業務相關的數據。約定以下圖所示:工具
以其中一個WMS回傳消息接口爲例:【入庫單收貨確認回傳接口】,其處理業務說明:WMS系統在入庫單完成入庫(上架)後,將對應入庫信息回傳給外部系統(即秀品)。EMS提供的文檔說明以下圖:post
結合秀品系統實現,EMS的回調最終只需拼接成這樣一個請求:性能
秀品某測試機Ip+http端口號+調用路徑+servicename+appkey+content(xml格式)
其中:Ip+端口+調用路徑+appkey 與測試環境配置相關,基本不隨業務變化。
servicename+content(xml格式)和業務有關,頻繁變化。
針對該【入庫單收貨確認回傳接口】,則只需拼接並執行這樣一個請求:
http://host:port/oms/wms/ems?service=WmsStockInConfirm&appkey=xxxxxx&content=< RequestReceiveInfo> xxxxxxxx</RequestReceiveInfo>
說明:content爲上圖中xml格式的數據集。
如何處理這類mock測試?
WAY1:尋找能發送http請求(get\post)的測試工具,例如fiddler、postman。
fiddler你們都比較熟悉,主要介紹下項目中使用的postman。Postman 是Chrome 擴展,提供功能強大的 Web API & HTTP 請求調試。它可以發送任何類型的HTTP 請求 (GET, HEAD, POST, PUT..),附帶任何數量的參數+ headers。其具有兩個主要優勢:
1.可以保留歷史請求,這樣咱們就能夠很容易地從新發送請求;
2.有一個「集合(collection)」功能,用於存儲全部請求相同的API/域。
使用效果如圖:
Postman其實已足以知足大部分同類測試需求,且使用成本不高,不需額外編寫測試代碼。但結合咱們項目特色,這些mock會影響每一次訂單流程扭轉的測試,使用頻率很是高,且存在許多須要mock的回調接口。因此,針對這些影響可得出如下可改進點:
1.數據主要集中在xml中,每次執行需根據不一樣測試數據更改xml,改起來費時費力且易出錯。
2.雖有「集合」功能,但一我的的測試集也不便於及時共享給其餘同窗。
3.操做界面雖有b格,但過於簡陋,真心不便。
綜合postman的優缺點,不如嘗試把測試集固化到java代碼裏,所以開始了嘗試WAY2:利用java代碼,基於httpclient發送請求。相似於http接口測試,測試集代碼以下圖:
說明:
分別構造出請求url,xmlinfo及所需各參數後,執行請求便可。針對xml的處理,每次執行只需參照代碼註釋更改相應框內的屬性值便可,減小編輯時間和出錯機率,且一人寫的代碼其餘同窗均可以共用,整體仍是提升了測試效率,基本知足了測試需求,但仍存有可改進點:
1.執行時要基於IDE,須要更改xml文件中相應屬性值,同時必須具有代碼運行環境。
2.沒有可視化操做界面,存在使用門檻,操做不夠方便。
若是傳參更爲簡單,使用者無需接觸測試代碼,不用基於本地運行環境且可以可視化執行,這樣可進一步提高測試效率,因而開始了嘗試WAY3:模板語言在mock測試中的應用,並結合jenkisn實現用戶界面。最便捷的方式首先想到告終合jenkins,經過運行jekins job,只需在可視化的界面裏傳入參數值,即可「一鍵執行」成功模擬出接口的回調,很好地解決待改進的問題。
針對該解決方案:
首先,測試代碼需上傳服務器,需解決服務器上構建打包的規範問題,以即可以經過命令行傳入參數調用到不一樣測試類及模板文件。
其次,針對xml文件做爲請求參數,考慮引入FreeMarker模板引擎,基於模板生成xml文件輸出。提取出xml中在實際測試場景中需頻繁更新的屬性,從新定義成一個Java do類,向匹配的ftl文件傳值。從而總體簡化測試代碼的繁鎖度。
另外,從工具使用角度考慮,傳參過多,也會較繁鎖,因此考慮將輸入的參數合併爲長字符串,傳遞到程序後再作拆分處理。
總之,在設計代碼結構及編寫程序時,秉承着一個原則:儘量通用化。
結合最終需拼接並執行的請求形式:
Ip+端口+調用路徑+servicename+appkey+content(xml);
其中Ip+端口+調用路徑+appkey 與測試環境配置相關,基本不變;
servicename+content(xml)和業務有關,頻繁變化。
作了以下改進:
1.將請求url中環境配置相關的共通部分抽取,定義爲CommonURLDo,以即可以靈活運行在不一樣的測試環境。
2.將不一樣業務接口(servicename)對應的xml定義爲不一樣的ftl模板文件。並將模板需頻繁變化的變量提取,定義成業務DO類,創建DO和ftl的映射,經過DO向ftl傳參。
3.爲測試類更通用,將ServiceName參數化,經過傳入的ServiceName,渲染出相應的ftl模板文件。一個測試主類即可支持全部同類的需求。
4.最後,針對一個業務場景,配置相應jenkins job,傳入三部分必需的參數:【測試類名】+【與環境配置相關的通用信息】+【xml文件需頻繁變化的屬性值】,執行job,即可完成一次回調模擬。
如圖,代碼結構組織及大致實現以下:
首先,定義ftl模板文件及相應DO。
其次,執行測試主類main方法,參數依賴於jenkins job執行傳入,執行主要分爲3個steps:
其中,step2中根據不一樣servicename調用不一樣業務處理類,實現以下:
最終,jenkins job的使用者界面以下:
藉助於jenkins的用戶界面,成功實現了「一鍵執行」。
那麼,來運行一個mock測試試試吧~
至此,一個完整的mock測試場景已成功完成。
在本身編寫和使用工具過程當中,也會不斷總結出一些待優化點,根據項目後續實際須要再作擴展。固然,如今這種方式仍有其侷限性:
1.若是能夠更通用,實現通用的mock server,client端使用時不需添加測試代碼且有操做頁面,只需在頁面上進行簡單配置即可成功執行測試;
2.可以以產品/項目維度對場景用例進行維護,共享並存儲一份測試case,維護管理更便捷;
3.可以提供對多種協議的支持,例如http、dubbo、hessian等;
4.對自動化測試和性能測試的支持,提供自動化的API調用,甚至能夠對一些壓力測試場景提供支持。
若是能夠實現一個通用mock測試平臺,總體上將更利於測試效率的提高。
更多網易技術、產品、運營經驗分享請點擊。
相關文章:
【推薦】 阿里雲PolarDB及其共享存儲PolarFS技術實現分析(上)
【推薦】 最小化局部邊際的合併聚類算法(中篇)
【推薦】 對雲環境下訪問控制系統的思考