黎素珍
摘要:隨著分布式服務(wù)的廣泛應(yīng)用,項目業(yè)務(wù)拆分后一般由不同業(yè)務(wù)團隊承建。各團隊的開發(fā)進度不一致而出現(xiàn)業(yè)務(wù)間依賴不可用的問題越來越突出。使用Mock技術(shù)可以十分便利的解決外部依賴。文中在介紹Mock概念的基礎(chǔ)上,引入了WireMock工具,并著重闡述WireMock的兩種運用方法。
關(guān)鍵詞:軟件測試;接口測試;模擬服務(wù);模擬對象;WireMock
中圖分類號:TP311? ? ?文獻標識碼:A? ? ?文章編號:1009-3044(2018)34-0255-02
1 引言
隨著互聯(lián)網(wǎng)時代的快速發(fā)展,分布式服務(wù)的應(yīng)用越來越廣泛,日常服務(wù)出現(xiàn)粒度細、業(yè)務(wù)復(fù)雜的特點。在自身的業(yè)務(wù)系統(tǒng)及其業(yè)務(wù)線上都存在許多獨立部署的接口、服務(wù)。Mock技術(shù),很大程度上保證了在研發(fā)、測試過程中,自身所依賴的服務(wù)隨時都可以使用,從而不阻礙各個團隊自身的研發(fā)、測試進度。一般來說,我們通過構(gòu)建Mock Service,并配置不同的輸入、數(shù)據(jù)和場景的方式,對依賴的接口進行Mock。構(gòu)建Mock Service的工具有許多,比如:moco、Mountebank、VCR、soapUI等,本文將介紹一款輕量級的Mock Service——WireMock。
2 Mock概述
Mock的意思是模擬,即通過某種技術(shù)手段創(chuàng)建一個虛擬的對象,模擬某些不易構(gòu)造或是不易獲取的對象的行為,返回預(yù)先的設(shè)計結(jié)果。
2.1 Mock的粒度
根據(jù)需要測試的對象大小,Mock的粒度是有區(qū)別的,從小到大主要分為三個粒度:
1) mock一個函數(shù):與待測試函數(shù)有關(guān)的交互全部使用mock方式替換。
2) mock整個類或接口:與待測試的類或是接口的交互全部使用mock方式替換;
3) mock整個系統(tǒng):與待測試的系統(tǒng)外部的交互全部使用mock方式替換。
總而言之,模擬外部依賴時需要明確的區(qū)分內(nèi)、外的邊界,以找到合適的切入點。在制定測試策略時可參照測試金字塔以便區(qū)分不同層次的測試關(guān)注點,如圖1。測試的粒度越大,測試的成本、效率、缺陷定位的難易程度均呈線性增長。WireMock工具的Mock粒度應(yīng)屬于第二種。
2.2 Mock的好處
WireMock測試工具主要用于接口測試領(lǐng)域。根據(jù)分層測試定義,最底層由開發(fā)人員編寫的單元測試保證代碼質(zhì)量[1],最頂層由功能測試人員進行手工或者UI自動化測試來保證功能的可用。接口測試的意義則在于能更早的發(fā)現(xiàn)問題、縮短研發(fā)周期及發(fā)現(xiàn)更加底層的問題等等。而對接口進行Mock的好處則在于:
1) 消除依賴項,研發(fā)團隊可以并行工作,且不影響研發(fā)進度;
2) 提前進入測試,更早的發(fā)現(xiàn)問題,提高測試效率。接口定義完成后,測試人員創(chuàng)建Mock,把接口提前添加到自動化測試平臺,起到TDD的效果;
3) 有效地增加覆蓋面:當某些場景無法通過正常方式操作時,可以模擬接口入?yún)崿F(xiàn)復(fù)雜的業(yè)務(wù)邏輯。
3 WireMock的應(yīng)用
WireMock,是一個開源的測試工具,最初是由Tom Akehurst在2011年創(chuàng)建的。它具有支持HTTP響應(yīng)存根、請求驗證、代理/攔截、錄制/回放以及故障植入等功能。WireMock可使用的HTTP方法包括GET、POST、PUT、DELETE、HEAD、TRACE、OPTIONS等,并支持自定義header、數(shù)據(jù)模板、URL Template、Query parameters匹配以及顯示指定文件內(nèi)容等等。工具是使用Java語言開發(fā)的,有兩種較為普遍使用方式:1)jar包單獨部署作為獨立的HTTP服務(wù)使用,這種方式基本能滿足大多數(shù)需求;2)通過引入依賴的方式在代碼中使用。
3.1 作為服務(wù)獨立運行
在官網(wǎng)下載一個獨立的可運行jar包,輸入命令:java –jar wiremock-standalone-2.19.0.jar來啟動WireMock。若未指定端口號,程序默認綁定端口號為8080,啟動后在當前目錄下會創(chuàng)建兩個空文件夾:__files和mappings:
1) __files文件夾用來放置測試的響應(yīng),如返回的json或字符串。當存根映射不匹配URL時,也支持從__files中讀取匹配文件進行響應(yīng)。假設(shè)__files/sample路徑下存在test.html文件,且存根映射與請求的URL不匹配,當請求http://<host>:<port>/sample/test.html時,程序?qū)⒎祷豞_files下對應(yīng)的文件信息。
2) mappings文件夾放置的*.json文件,用作請求響應(yīng)配置。*.json文件的名稱隨意,可以添加多個任意的文件。
3.1.1 模擬 POST請求接口
在mappings文件夾下創(chuàng)建一個*.json文件,以POST方法為例進行Mock,內(nèi)容如圖2。
客戶端發(fā)送POST請求http:// <host>:<port>/lwebtest/UserLogin來調(diào)用模擬的UserLogin接口。當請求body內(nèi)容與定義匹配(符合equalTo的內(nèi)容),則返回Response響應(yīng)。響應(yīng)可分為body直接返回和指定file返回(支持json、xml、html等)。此外,WireMock還提供了其他匹配符,如:matches、binaryEqualTo、equalToXml、matchesXPath等。
mappings文件夾中的*.json文件,除上述手動創(chuàng)建外,可以通過錄制生成,步驟如下:
1) 在瀏覽器中輸入WireMock的錄制地址:http://
2) 在Target URL中輸入目標URL后,再點擊Record按鈕進入錄制狀態(tài)。
3) 以上述UserLogin接口為例(WireMock部署的端口號為9000):使用Fiddler工具的Composer模塊發(fā)送Post請求:http://localhost:9000/lwebtest/UserLogin;WireMock接收到請求后,向目標服務(wù)器轉(zhuǎn)發(fā)請求http://localhost:8080/lwebtest/UserLogin,再將目標服務(wù)器返回的結(jié)果返回,并記錄請求及響應(yīng)的內(nèi)容。
4) 點擊Stop按鈕后停止錄制。此時,在mappings文件夾中會新生成一個.json文件,文件記錄了步驟3)中請求和響應(yīng)內(nèi)容。
5) 若后續(xù)再進行POST訪問http://localhost:9000/lwebtest/UserLogin接口時,WireMock將從已錄制的json文件中獲取對應(yīng)的響應(yīng)信息進行返回。錄制的json文件可以進行修改,以便模擬不同的請求及響應(yīng)內(nèi)容。注意,修改文件后內(nèi)容不能馬上生效,需重新啟動WireMock。
3.2 作為引入依賴的方式使用
WireMock自帶了一些JUnit的規(guī)則,用以服務(wù)器生命周期管理,并能進行配置/撤銷任務(wù)。接下來以Maven工程里JUnit使用WireMock為切入點進行說明。
首先,在pom.xml文件中,添加依賴:
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.19.0</version>
<scope>test</scope>
</dependency>
其次,為使WireMock支持基于測試用例進行啟動、停止,需將下文代碼添加到測試類(或父類)中:
@Rule
public WireMockRule wireMockRule = new WireMockRule(WireMockConfiguration.options().port(9000));
之后就可進行測試用例的編寫。WireMock 的打樁可分為兩種方式:Java代碼和json api。
1) Java代碼方式打樁:以圖3為例,測試代碼mock了一個get請求/lwebtest/bookinfo,返回結(jié)果中定義了狀態(tài)碼(200)、頭部信息(Content-Type)及body內(nèi)容。本例還引用了必要的匹配器和asserThat方法進行斷言。在最后使用了WireMock的verify對請求進行驗證。
2) json api方式打樁:通過文件或者代碼配置,在工程中/test/resources目錄下創(chuàng)建__files和mappings文件夾。然后,在mappings目錄下創(chuàng)建需要的*.json文件;之后就可以在測試代碼中使用http請求json中的url路徑。
4 結(jié)論
WireMock是國外接口測試領(lǐng)域針對API的知名Mock測試工具。它在易用性上存在些許不足之處,如需要編寫大量Mock API的規(guī)則,無法自動生成數(shù)據(jù)等。不過,相較其他Mock工具而言,WireMock的優(yōu)勢仍十分明顯:在隔離外部調(diào)用時,可以避免多服務(wù)之間的復(fù)雜情況(譬如網(wǎng)絡(luò)、其他研發(fā)小組的服務(wù)可用性等),并能以可重復(fù)的方式來模擬任何場景;可以較好地模擬一些大粒度的異常場景,如:網(wǎng)絡(luò)錯誤、Down機、SSL驗證失敗、請求響應(yīng)不匹配等等。WireMock運行十分穩(wěn)定,且反饋周期短,非常適合小型項目。
參考文獻:
[1] 蟲師.Web接口開發(fā)與自動化測試——基于Python語言[M].北京:電子工業(yè)出版社,2017.
[2] 潘詩瑤,黃建明.Web應(yīng)用系統(tǒng)中的MOCK測試技術(shù)[J].軟件,2016,37(12):214-218.
[3] 趙文杰.軟件開發(fā)中的自動化單元測試淺談[J].計算機光盤軟件與應(yīng)用,2014,17(21):74+76.
【通聯(lián)編輯:梁書】