Mock Server實踐

 

轉載自:《Mock Server實踐》閆帥:http://tech.meituan.com/mock-server-in-action.htmlphp

 

背景

 

 

在美團服務端測試中,被測服務一般依賴於一系列的外部模塊,被測服務與外部模塊間經過REST API或是Thrift調用來進行通訊。要對被測服務進行系統測試,通常作法是,部署好全部外部依賴模塊,由被測服務直接調用。然而有時被調用模塊還沒有開發完成,或者調用返回很差構造,這將影響被測系統的測試進度。爲此咱們須要開發樁模塊,用來模擬被調用模塊的行爲。最簡單的方式是,對於每一個外部模塊依賴,都建立一套樁模塊。然而這樣的話,樁模塊服務將很是零散,不便於管理。Mock Server爲解決這些問題而生,其提供配置request及相應response方式來實現通用樁服務。本文將專門針對REST API來進行介紹Mock Server的總體結構及應用案例。html

 


"mock server背景"

名詞解釋

  • Mock規則:定義REST API請求及相應模擬響應的一份描述。
  • Mock環境:根據請求來源IP來區分的Mock規則分組。Mock Server能夠定義多套Mock環境,各套環境間相互隔離。同一個IP只能對應一個Mock環境,不一樣的IP能夠對應同一個Mock環境。

總體結構

 

Mock Server由web配置頁面Mock Admin及通用Mock Stub組成:Mock Admin提供了web UI配置頁面,能夠增長/刪除請求來源IP到Mock環境的映射,能夠對各套環境中的Mock規則進行CRUD操做;Mock Stub提供通用樁服務,對被測系統的各種REST API請求調用,返回預先定義好的模擬響應。爲了提升樁服務的通吐,使得樁服務能在被測系統壓力測試中獲得好的表現,咱們開啓了5個樁服務,經過Nginx作負載均衡。Mock Server的總體結構以下圖所示。java

 


"mock server總體結構"

數據存儲

  • 將請求來源IP到Mock環境名的映射存儲到mock-env.conf中,mock-env.conf的每一行定義了一條映射,如:
    192.168.3.68 閆帥的測試機環境
    這條映射代表來源是192.168.3.68的請求,使用Mock環境名爲閆帥的測試機環境的Mock規則。
  • 將配置的Mock規則存放到<對應Mock環境名>.xml中,下面部分展現了Mock規則的存儲格式。
<configuration>
...
  <mock id="716add4f-33f7-49ac-abf3-fc617712ffea" name="test001" author="yanshuai">
    <request>
      <uri>/api/test/.*</uri>
      <method>GET|POST|PUT|DELETE</method>
      <parameters>
        <parameter name="name" value="test.*"/>
        ...
      </parameters>
      <headers>
        <header name="nb_deviceid" value="1E[0-9a-zA-Z]+"/>
        ...
      </headers>
    </request>
    <response delay="1000" real="false">
      <statusCode>200</statusCode>
      <format>application/json;charset=UTF-8</format>
      <customHeaders>
        ...
      </customHeaders>
      <body>{&quot;name&quot;:&quot;閆帥&quot;}</body>
    </response>
  </mock>
...
</configuration>

Mock Stub

 

當請求發送到Mock Stub時,Mock Stub會根據請求的來源IP找到對應的獨立環境名,而後根據獨立環境名獲取全部預約義的Mock規則,遍歷這些Mock規則,若是找到一條規則與接受到的請求匹配,那麼返回預約義的模擬響應。若是找不到規則匹配,那麼返回404錯誤。其中,規則匹配是根據請求中的uri/method/headers/parameters/body是否與Mock規則中定義的對應字段正則匹配來定的。android

 


"mock stub工做原理"

Mock Admin

  • 打開Mock Admin配置頁面,若是還沒有映射來源IP地址到環境,則點擊環境列表導航連接,進入環境列表頁面,點擊添加,輸入源IP及環境名,點擊肯定按鈕,實現源IP到所設環境的映射。

    "mock admin環境列表"
  • 點擊規則列表,規則列表頁面將默認羅列出default環境的全部Mock規則(如「語音登陸code獲取」規則)。從新選擇環境,能夠羅列出所選環境中的Mock規則。每一個Mock規則都處於詳細信息展開的狀態。點擊「所有摺疊」按鈕,將把全部的規則詳細信息給隱藏;點擊「所有展開」按鈕,將把全部的規則詳細信息給展開。點擊「只顯示本人建立的規則」,將過濾獲得mis帳戶用戶建立的規則。點擊「按建立時間排序」的開關按鈕,將實現Mock規則的升序/降序顯示。

    "mock admin規則列表"
  • 點擊導航欄的「新建規則」選項,能夠建立一個Mock規則,須要填寫規則名稱、請求及響應,並選中環境。對於請求,須要填寫URL及勾選Method,若是要求對於符合某種規則的請求才被Mock,則填寫對應的Headers/Parameters/Body Like,這些數據都是正則匹配的形式。對於響應,若是勾選了「返回真實響應」,則只須要關注延時(延時是指返回請求須要的sleep時間,單位是毫秒)。此時須要將請求的URL地址給寫完整了,須要包含host(IP)及port,不能只是path。若是不勾選「返回真實響應」,則將返回模擬響應。Status Code填寫返回碼,好比200,404;Format選擇返回數據的格式,好比json,html等;還能夠返回自定義的Headers及響應的Body。點擊新建按鈕之後,若是建立成功,則提示成功建立,並跳轉到規則列表頁面。

    "mock admin新建規則"
  • 對於一個建立好的Mock規則,能夠點擊Action下拉菜單,進行操做。若是點擊「克隆」,則跳轉到「新建規則」頁面,並將克隆的Mock規則信息給填充進去;點擊「編輯」,則跳轉到更新頁面,更新頁面填充了要編輯的Mock規則信息;點擊「刪除」,則彈出確認刪除對話框,點擊肯定按鈕,將刪除此規則;點擊取消按鈕,則取消刪除操做。若是此Mock規則處於詳細信息展開狀態,則可點擊摺疊來隱藏詳細信息;若是處於詳細信息摺疊狀態,則可點擊展開選項,將顯示詳細信息。上移選項,能夠將Mock規則上移一位;下移選項,能夠將Mock規則下移一位。

    "mock admin規則操做"

使用方式

  1. 修改被測服務的HTTP依賴,將依賴的IP和端口分別設置爲mock.ep.sankuai.com和80,並重啓被測服務;
  2. 建立Mock規則;
  3. 調用被測服務的API,被測服務將調用Mock服務;
  4. 刪除Mock規則(可選)。

編程使用

 

建立/刪除Mock規則,除了可經過Mock Admin頁面配置外,Mock Server還提供了SDK方式,用戶能夠經過編碼來使用Mock Server。web

 

  • 在Maven工程pom.xml中添加mock-client依賴
<dependency> <groupId>com.sankuai.meituan.ep.mockserver</groupId> <artifactId>mock-client</artifactId> <version>1.0.6</version> </dependency> 
  • 建立/刪除Mock規則
// 構造Mock規則 MockRule rule = new MockRule(); rule.setMockName("test-" + System.currentTimeMillis()); // Mock name必須設置 rule.setAuthor("yanshuai"); // author必須設置,設置爲代碼編寫者的mis帳號前綴,好比lining03 MockRequest mockRequest = new MockRequest(); mockRequest.setUri("/api/test/" + System.currentTimeMillis()); // Mock請求的uri必須設置 /** * Mock請求的方法必須設置 * 若是隻有GET請求,則寫成GET; * 若是有GET請求及PUT請求,則寫成GET|PUT; * 即用|分割請求方法,不能有空格。 */ mockRequest.setMethod("POST|GET"); // 必要的話,設置Mock請求的匹配header List<MockRequestHeader> mockRequestHeaders = new ArrayList<MockRequestHeader>(); mockRequestHeaders.add(new MockRequestHeader("device", "android2.3")); mockRequest.setHeaders(mockRequestHeaders); // 必要的話,設置Mock請求的匹配參數 List<MockRequestParameter> mockRequestParameters = new ArrayList<MockRequestParameter>(); mockRequestParameters.add(new MockRequestParameter("wd", "123.*")); mockRequestParameters.add(new MockRequestParameter("version", "v1")); mockRequest.setParameters(mockRequestParameters); rule.setMockRequest(mockRequest); MockResponse mockResponse = new MockResponse(); mockResponse.setDelay(1000L); // 設置Mock響應的延時 mockResponse.setStatusCode(200); // 設置Mock響應的狀態碼 /** * 設置Mock響應的格式 * 若是是json返回,則爲application/json;charset=UTF-8; * 若是是文本返回,則爲text/plain:charset=UTF-8; * 若是是xml返回,則爲text/xml;charset=UTF-8; * 若是是html返回,則爲text/html;charset=UTF-8。 */ mockResponse.setFormat("application/json;charset=UTF-8"); List<MockResponseHeader> mockResponseHeaders = new ArrayList<MockResponseHeader>(); // 設置Mock響應的header mockResponseHeaders.add(new MockResponseHeader("customHeaderName", "customHeaderValue")); mockResponse.setMockResponseHeaders(mockResponseHeaders); mockResponse.setBody("{\"code\":200}"); // 設置Mock響應的body rule.setMockResponse(mockResponse); // 建立Mock規則 final MockClient client = new MockClient(); String id = client.addRule("default", rule); // default爲環境名,若是使用別的環境,則填寫別的環境名 // 調用被測服務的API,被測服務將調用Mock服務 // 省略調用代碼... // 刪除Mock規則 client.removeRule("default", id); // default爲環境名,若是使用別的環境,則填寫別的環境名 

典型案例

  1. 相同Mock環境,同一接口,不一樣參數,能夠有不一樣的Mock結果
    按照下圖,依次建立這兩條規則(順序相關),而後在default環境對應的機器上,訪問http://mock.ep.sankuai.com/user/v1/info?token=fake,返回{"code":401,"type":"sys_err_auth_fail","message":"invalid token"};訪問http://mock.ep.sankuai.com/user/v1/info?token=other,返回{"user": {"id": 29008301,"mobile": "15001245907","isBindedMobile": 1}}。

    "案例1_1"
    "案例1_2"
  2. 真實請求延時Mock
    按照下圖建立規則,在閆帥的測試機環境對應的機器上,訪問http://mock.ep.sankuai.com/api/v1/divisions,將延遲5s返回城市列表json串。

    "案例2"
  3. 不一樣Mock環境,徹底相同的接口參數,能夠有不一樣的Mock結果
    按照下圖建立規則,在閆帥的測試機環境對應的機器上,訪問http://mock.ep.sankuai.com/cachier/paynotify返回值是failure;在支付php環境對應的機器上,訪問http://mock.ep.sankuai.com/cachier/paynotify返回值是success。

    "案例3_1"
    "案例3_2"
 
 
http://www.mock-server.com/where/downloads.html
相關文章
相關標籤/搜索