黎素珍


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