基於Wiremock創建Mock Service平台


轉載:http://blog.csdn.net/liuchunming033/article/details/52399397

1、Wiremock工具介紹

一般開發項目都會分模塊進行,比如都會把前端和后端分開,在前端和后端里面也通常是分模塊開發的。當開發進度不一致時,可以對依賴接口構建Mock Service,模擬不同輸入/數據/場景,這樣不至於影響本模塊的開發進度。構建Mock Service方法很多,今天介紹Wiremock,Wiremock非常輕便易用,甚至不用編程,一個jar包基本夠用了,當然,也可以把它引用寫進測試代碼里。

官網地址:http://wiremock.org/

Jar包下載:http://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.1.10/wiremock-standalone-2.1.10.jar

2、Wiremock工作原理

啟動wiremock

java -jar wiremock-2.1.10-standalone.jar –port 9999 —verbose
  • 1

(–port設定端口為9999; –verbose開啟日志。更多參數需要參考: 
http://wiremock.org/docs/running-standalone/ 
啟動后在同目錄下生成兩個空的文件夾:__files和mappings。__files是放上傳/下載/錄制文件的,mappings放response和request url的映射的。 
在mappings文件夾下隨便創建一個*.json文件,比如長下面這樣:

"request": { "method": "GET", "url": "/api/testdetail" }, "response": { "status": 200, "bodyFileName": "testdetail.json”, "headers": { "Content-Type": "application/json", "Cache-Control": "max-age=86400" } } }

 

bodyFileName還可以是html、xml等文檔。 
在瀏覽器或者使用curl命令,調用http://localhost:9999/api/testdetail,就能返回testdetail.json的內容了。testdetail.json就是需要我們在__files里面建立的響應文件。wiremock也支持直接在response結構體中返回響應內容,比如在mapping文件中,將response寫成下面這樣:

"response": { "status": 200, "body": “Hello world ", "headers": { "Content-Type": "application/json", "Cache-Control": "max-age=86400" }

 

當發送請求時候,將直接返回“Hello world”。

3、Wiremock支持的HTTP方法

HTTP方法支持GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS等,自定義頭、數據模板(bodyPatterns,如不符合,拋出404錯誤),URL Template,Query參數匹配,顯示指定文件內容等。下面將介紹如何使用wiremock實現這些。

3.1 POST

POST http://localhost:9999/api/products


{
    "request": { "method": "POST", "url": "/api/products", "bodyPatterns": [ {"equalToJson" : "{ \"name\": \"new product\", \"creator\": \"tester\", \"createTime\": \"2015-09-07\" }", "jsonCompareMode": "LENIENT"} ] }, "response": { "status": 201, "body": "Add successfully.", "headers":{ "x-token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } }

 

3.2 PUT

PUT: http://localhost:9999/api/products/1

{
    "request": { "method": "PUT", "url": "/api/products/1", "bodyPatterns": [{ "equalToJson": "{ \"id\": 1, \"name\": \"new product\", \"creator\": \"tester\", \"createTime\": \"2015-09-07\" }", "jsonCompareMode": "LENIENT" }] }, "response": { "status": 200, "body": "Update successfully.", "headers": { "x-token": " xxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } }

 

3.3 DELETE

DELETE: http://localhost:9999/api/products/1


{
    "request": { "method": "DELETE", "url": "/api/products/1" }, "response": { "status": 204, "headers":{ "x-token":" xxxxxxxxxxxxxxxxxxxxxxxxxxxx" } } }

 

3.4 URL Matching

URL Matching: http://localhost:9999/api/products/1(2/3…)

{
    "request": { "method": "GET", "urlPattern": "/api/products/[0-9]+" }, "response": { "status": 200 } }

 

3.5 Query參數匹配

Query參數匹配:http://localhost:9999/api/products?search=china

{
    "request": { "method": "GET", "urlPath": "/api/products", "queryParameters": { "search": { "contains": "chin" } } }, "response": { "status": 200, "headers": { "Content-Type": "application/json" }, "body": "{ \"id\": 7, \"name\": \"shan zai\", \"from\":\"China\" },{ \"id\": 7, \"name\": \"shan zai\", \"from\":\"China(RPC)\" }" } }

3.6 模擬錯誤

模擬404錯誤


{
    "request": { "url": "/unknown.html", "method": "GET" }, "response": { "status": 404, "headers": { "Content-Type": "text/html; charset=utf-8" } } }

 

 

3.7 設置響應延遲

{
    "request": { "method": "GET", "url": "/delayed" }, "response": { "status": 200, "bodyFileName": "mytest.json", "headers": { "Content-Type": "application/json", "Cache-Control": "max-age=86400" }, "fixedDelayMilliseconds": 2000 } }

4、Mock Service平台化

使用WireMock通過mappings和__files文件夾可以有效管理映射和返回內容文件。而這兩個文件目前是手動編輯,如果可以做成平台化管理,所有接口通過創建完成,文件命名規則全部由系統進行管理,將節省的時間更多投入業務關注和及早進行自測,這樣子的收益將會更大。

那怎么樣的平台才算能夠滿足當前需求呢?

基於HTTP協議 
支持Url、UrlPattern匹配、Query參數 
支持數據存儲 
API接口規范化管理 
提交表單即可生成mapping和__files所需文件 
不同項目接口有不同的前綴 
能夠返回指定格式(json、xml、html等)內容 
能夠設定響應延遲 
設置cookies 
設置headers 
支持用戶驗證

根據需求設計總體架構如下: 
包括前台和后台。前台負責接受用戶的Mock設置,后台負責將用戶的設置轉換為WireMock所需要的mapping和__file文件,並提供查詢功能。 
MockServer架構圖 
這里寫圖片描述
根據架構圖,做了總體設計如下: 
這里寫圖片描述
頁面分為Mock項目管理和Mock API管理。Mock項目管理可以創建、修改、刪除Mock項目,Mock PAI管理可以創建、修改、刪除Mock的API。后台管理負責生成mapping和file文件、對wiremock進行重啟等。

4.1 技術選型

由於大家對python都比較熟悉,也有過使用python的Flask框架進行開發經驗,這次依然采用Flask+Mysql的方案。從界面錄入到mapping、_files文件生成處理采用Python,后台工具使用WireMock的standalone模式,通過shell腳本進行一鍵啟停管理,以及實時刷新url、mapping映射。

4.2 Mock項目管理頁

4.2.1 添加項目

配置協議、進行mock服務器的重啟、重新加載(有新的mapping、file文件生成系統會自動reset即可,當然手工reset也可以,即時加載無須重啟服務等待)。 
這里寫圖片描述

4.2.2 顯示項目

4.2.3 修改項目

4.2.4 刪除項目

4.3 Mock API管理頁

4.3.1 添加API

選擇方法、URL類型,填寫URL(如果選擇URL類型為UrlPattern,則填寫正則表達式),填寫狀態碼、返回接口,以及返回頭,就可以完成一個mock接口的創建。這些信息要存儲到Mysql。 
這里寫圖片描述
1)手工輸入 
適合響應體比較短小的情況 
這里寫圖片描述
2)通過url獲取 
返回體比較大,目標Mock接口已經存在,可以直接抓取生成文件; 
這里寫圖片描述
3)上傳文件的方式 
返回體比較大、目標Mock接口還未開發完成,手工上傳返回內容的文件即可。 
這里寫圖片描述
以上三種靈活的保存返回內容方式,最終保存的接口會按照以下格式生成mapping和__files所需文件。 
這里寫圖片描述

4.3.2 顯示API

展示列表,列出相關URL、方法、是否正則、返回碼、返回類型。 
這里寫圖片描述

4.3.2 修改API

4.3.3 刪除API

4.4 MockServer后台

使用Java-WireMock進行后台服務,在項目配置頁通過按鈕:重啟、重新加載,調用后台腳本:wiremock_controller.sh,腳本內容參考:

#!/bin/bash if [ "$#" = 0 ];then echo "Usage: $0 (start|stop|restart|reset)" exit 1 fi dirWiremock=`pwd` getCount=`ps -ef | grep "wiremock-1.53-standalone" | grep -v "grep" |wc -l` wiremock_jar=${dirWiremock}/wiremock-1.53-standalone.jar port=9999 wiremock_url=http://localhost:${port} stop(){ count=${getCount} if [ 1==${count} ];then curl -d log=aaa ${wiremock_url}/__admin/shutdown echo "Stop success!......" else echo "Already stop" fi } start(){ count=${getCount} if [ 0==${count} ];then nohup java -jar ${wiremock_jar} --verbose=true --port=${port} & echo "Start success!......" else echo "Already start" fi } if [ "$1" = "restart" ];then count=${getCount} if [ 1==${count} ];then echo "Wiremock is running,wait for restarting! ...." stop echo "Start wiremock......" start else start fi elif [ "$1" = "start" ];then echo "Start wiremock......" start elif [ "$1" = "stop" ];then echo "Stop wiremock......" stop elif [ "$1" = "reset" ];then count=${getCount} if [ 0==${count} ];then echo "Wiremock must be running before reset,wait for starting! ...." start fi curl -d log=aaa ${wiremock_url}/__admin/mappings/reset echo "Reset success!......" fi

其中: 
“nohup java -jar wiremockjarverbose=trueport={port} &”:在linux系統后台運行WireMock; 
“curl -d log=aaa ${wiremock_url}/__admin/mappings/reset”:是通過發送POST請求,重新加載新生成的配置文件。

5、總結

Mock API接口是非常必要的,因為不同研發組的系統之間的數據交互往往是通過接口來實現,當不同組接口開發不同步時,接口測試無法及早參與,對接調試比較困難。這樣勢必導致軟件開發迭代變慢,沒有時間對質量進行充分驗證。 
可以借鑒《自動化單元測試實踐之路》在單元測試中,使用Mockito對依賴進行Mock,那同樣道理,使用Mock技術也可以對HTTP API進行Mock,按照這個思路探索下去,看看有沒有開源解決方案,是否能夠解決當前問題,如果可以就不用重復寫一套解決方案;如果不行,那能否基於開源的做二次開發呢?

6、參考文檔

http://wiremock.org/docs/ 
http://www.infoq.com/cn/articles/evolution-of-httpservermock-from-hand-to-platform/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM