Mock 這個詞對于測試人員來說并不陌生,當(dāng)我們要測試的接口 A 依賴接口 B ,可 B 無法滿足我們的測試需求時,需要 Mock 一下接口 B,來測試 A。當(dāng)前端和服務(wù)端并行開發(fā)時,如果服務(wù)端接口還沒有開發(fā)好,前端同學(xué)也會 Mock 一下。
那 Mock 到底是什么?
維基百科:
在面向?qū)ο蟪绦蛟O(shè)計中,模擬對象(英語:mock object,也譯作模仿對象)是以可控的方式模擬真實對象行為的假的對象。程序員通常創(chuàng)造模擬對象來測試其他對象的行為,很類似汽車設(shè)計者使用碰撞測試假人來模擬車輛碰撞中人的動態(tài)行為。
注意這里的關(guān)鍵信息,以可控的方式,模擬真實對象行為,假的對象。
為什么要模擬呢?
一定是因為沒有辦法或者不需要用真實的服務(wù),比如:
真實的對象還沒開發(fā)好,但你又急需測試;
真實的對象是第三方的(比如各種開放平臺),沒有提供聯(lián)調(diào)環(huán)境,或是不便聯(lián)調(diào),或是搭建很麻煩;
真實的對象無法覆蓋你要的測試場景(比如網(wǎng)絡(luò)錯誤),而使用 Mock,你想要什么就可以模擬什么;
真實的對象速度很慢,而模擬的非???;
等等。
這些情況下,模擬對象是一個非常好的解決方案,它可以讓你的測試不被阻斷,還能模擬出你想要的各種場景。
但模擬,不是真實,模擬是按照我們設(shè)定的劇本在走,是我們自己控制的,而真實的情況可能存在各種不確定性,所以不能完全相信 Mock。另外,Mock 是把真實對象模擬了一遍,如果真實對象改了,模擬對象也得跟著改,數(shù)量一多,維護(hù)起來也是十分的麻煩。
怎么 Mock ?
本文介紹我們團(tuán)隊在實際的項目中遇到的 3 種 Mock 場景,以及我們的設(shè)計方案。
案例1. Mock HTTP:通過域名映射實現(xiàn) Mock
項目背景
我們要測試一個 HTTP 接口,這個接口在服務(wù)內(nèi)部的處理會因地區(qū)不同而存在差異,雖然對外提供的業(yè)務(wù)接口只有 1 個,但在服務(wù)內(nèi)部,如果判斷是 A 地區(qū)就會去調(diào)用 A 地區(qū)的接口,B 地區(qū)會去調(diào)用 B 地區(qū)的接口,不同地區(qū)通過域名區(qū)分。
比如,要測的是登錄接口 test.com/login,到了內(nèi)部處理時就會因不同的地區(qū)去調(diào)用不同接口:
A 地區(qū)會調(diào)用:test.a.com/login
B 地區(qū)會調(diào)用:test.b.com/login
C 地區(qū)會調(diào)用:test.c.com/login
......
如下所示:
為了便于測試,我們需要 Mock 各個地區(qū)的接口,應(yīng)該怎么做呢?
設(shè)計方案
方案如下:
在「中臺」所在的服務(wù)器上,將調(diào)用 A 地區(qū)接口的域名通過 hosts 中的配置映射到 Mock 平臺的 IP。配置好以后,「中臺」調(diào)用 A 地區(qū)的接口時,請求都會轉(zhuǎn)發(fā)到 Mock 服務(wù)器上,然后我們就可以在 Mock 服務(wù)器上對具體的接口進(jìn)行配置,定制返回信息;
需要 Mock 多個地區(qū)時,將對應(yīng)域名加到 hosts 里映射即可。當(dāng)然也可以 Mock 一個固定的域名,如 test.mock.com,然后每個地區(qū)的域名進(jìn)行配置化(配置中心)。當(dāng)我們要 Mock 某個地區(qū)時,只需將該地區(qū)的配置的域名改為 test.mock.com 即可,這樣就不用去修改 hosts 文件了。
這種方案的優(yōu)點是:
沒有代碼侵入,域名可通過 hosts 進(jìn)行配置,將不同的域名映射到 Mock 服務(wù)器;
配置簡單,沒有什么門檻;
缺點是:
依賴的數(shù)據(jù)需要我們自己來配置,這需要額外投入精力去研究被依賴服務(wù)的接口信息,還要維護(hù) Mock 數(shù)據(jù);
Mock 控制粒度比較粗。在無任何代碼侵入的前提下,比如在測試 A 地區(qū)的接口時,需將被調(diào)用的所有接口都進(jìn)行 Mock,而不能只 Mock 其中幾個接口。
僅支持 Mock HTTP 請求。
案例2. Mock RPC:基于 AOP 實現(xiàn) Mock
項目背景
這個項目對另外一個項目有強(qiáng)依賴,并且我們對這個 Mock 方案的要求是,除了能滿足我們自己的常規(guī)測試外,還要能提供給外部客戶進(jìn)行快速對接、聯(lián)調(diào),要能支持 HTTP 和 RPC(Dubbo)。
設(shè)計方案
為了滿足這個需求,我們開發(fā)了Mock SDK。
SDK 中包含幾個攔截器:
AbstractAspect類:是一個抽象切面攔截器,是其它攔截器的父類,提供了一些抽象方法讓子類實現(xiàn),以及一些通用的方法。
ControllerAspect類:HTTP 接口攔截器,負(fù)責(zé)獲取接口的 URL、獲取全部請求頭、獲取全部請求參數(shù)、獲取全部請求體數(shù)據(jù)。
FacadeAspect類:Dubbo 接口攔截器,負(fù)責(zé)獲取方法名及其參數(shù)。
AnnotationsAspect類:注解切面攔截器,當(dāng) Java 類不在 client 下,但是需要 Mock 對應(yīng)的方法時,可以在該方法前加上注解@Mock。
使用時只需:
在pom文件中引入 Mock SDK;
spring-scan-bean配置 Mock 的工具類,加載到 spring 上下文容器中;
設(shè)置 Mock 開關(guān)配置。開啟 Mock 模式時,默認(rèn)會對所有controller中的接口、client中的 Dubbo 方法以及所有加了 Mock 注解的方法進(jìn)行攔截。
方案如下:
這種方案的優(yōu)點是:
支持 Mock HTTP,提供給客戶聯(lián)調(diào)測試時可在controller層進(jìn)行 Mock,但不推薦這么做,客戶自己 Mock HTTP 接口會更靈活;
支持 Mock RPC,我們自己測試時可在client層進(jìn)行 Mock;
Mock 粒度更細(xì):支持按接口粒度進(jìn)行 Mock,還支持單個 Java 方法添加注解來實現(xiàn) Mock;
Mock 節(jié)點靈活:controller層、client層、或加了 Mock 注解的 Java 方法均可。
缺點是:
性能問題:在 Mock 開啟模式下,每次請求都會去判斷是否存在 Mock 對象,接口性能會有一定程度受影響。
Dubbo 接口目前只在client層做的切面,所以在 Mock 平臺配置返回值時,出參字段沒辦法從接口文檔中直接獲取,因為client層的出參字段與接口文檔的參數(shù)字段不完全一致。
存在代碼侵入。就算在 Mock 配置為關(guān)閉的情況下,仍會生成一個無邏輯的切面。
案例3. Mock Python:基于數(shù)據(jù)存儲中間件實現(xiàn) Mock
項目背景
該項目也是需要對接多個區(qū)域,不同區(qū)域的接口存在很大差異,而且被測服務(wù)的末端是 Python 服務(wù)。另外一個重要的點是:該項目的測試數(shù)據(jù)非常有限且不可重復(fù)利用。
其實用「方案1」去 Mock 接口也是可以的,但:
需要花很多時間去預(yù)研 Mock 數(shù)據(jù);
被依賴服務(wù)的接口加解密方式、調(diào)用鏈路差異很大;
配置成本過高:比如一個登錄功能,有些區(qū)域可能需要調(diào) 5 個接口,有些可能要 7 個接口才能實現(xiàn);為了實現(xiàn)一個業(yè)務(wù)功能,往往需要配幾十個接口的 Mock。
因此在權(quán)衡了時間、資源、風(fēng)險利弊之后,我們采取了新的 Mock 方案 —— 基于數(shù)據(jù)存儲中間件的 Mock,我們用的是 Redis。
設(shè)計方案
基于數(shù)據(jù)存儲中間件的 Mock 方案其實是在被測服務(wù)中加入 Mock 邏輯,當(dāng)啟用 Mock 時,直接從 Redis 獲取數(shù)據(jù),而不去請求真實的數(shù)據(jù),這就實現(xiàn)了 Mock 的目的。
Mock 方法:
配置 Mock 開關(guān),便于開啟和關(guān)閉;
在 Redis 中配置 Mock 對應(yīng)的Key/Value;
優(yōu)點:
無需額外搭建 Mock 平臺,研發(fā)投入成本低;
無需關(guān)注各區(qū)域接口差異,Mock 的數(shù)據(jù)格式統(tǒng)一;
配置和維護(hù)成本低,也可編寫腳本實現(xiàn)批量 Mock。
缺點:
業(yè)務(wù)代碼驗證不全,Python 服務(wù)的業(yè)務(wù)代碼是驗證不到的。所以,Mock 測試之后,還要用僅存的真實數(shù)據(jù)去驗證一遍。
存在代碼侵入。為實現(xiàn) Mock 功能,存在非業(yè)務(wù)性邏輯。
總結(jié)
上述這 3 個案例就是我們在實際項目中遇到并實踐過的 Mock 方案,當(dāng)然還有其他的方案,這需要結(jié)合項目的實際情況綜合評估風(fēng)險、資源、利弊后再做選擇。本文只是提供了一些思路,希望對大家有所啟發(fā)。
審核編輯:黃飛
-
HTTP
+關(guān)注
關(guān)注
0文章
511瀏覽量
31573 -
數(shù)據(jù)存儲
+關(guān)注
關(guān)注
5文章
986瀏覽量
51118 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
66瀏覽量
7066
原文標(biāo)題:我們用到的3種Mock測試方案
文章出處:【微信號:TestinChina,微信公眾號:Testin云測】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
常見的三種無線接入方式是什么?
STM32的三種復(fù)位類型
STM32的三種boot模式介紹
三種不同的“防 Ping”技巧
SD-WAN三種不同場景的部署和實踐
測試工程師的三種分支
三種pads解決方案的對比
總結(jié):伺服電機(jī)三種不同的控制方式介紹資料下載
![<b class='flag-5'>總結(jié)</b>:伺服電機(jī)<b class='flag-5'>三種</b>不同的控制方式介紹資料下載](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Redis實現(xiàn)限流的三種方式分享
測試開發(fā)實踐:網(wǎng)關(guān)路由功能及測試
![<b class='flag-5'>測試</b>開發(fā)<b class='flag-5'>實踐</b>:網(wǎng)關(guān)路由功能及<b class='flag-5'>測試</b>](https://file.elecfans.com/web2/M00/57/51/pYYBAGLgrMuAf7_SAAArPJ1CGSA980.png)
DAB Announcement高效測試方案及應(yīng)用分析
![DAB Announcement高效<b class='flag-5'>測試</b><b class='flag-5'>方案</b>及應(yīng)用分析](https://file.elecfans.com/web2/M00/54/76/poYBAGLXvTKAJC3mAADQ64hwK-g275.png)
無人機(jī)測深的三種方法總結(jié)
![無人機(jī)測深的<b class='flag-5'>三種</b>方法<b class='flag-5'>總結(jié)</b>](https://file1.elecfans.com/web2/M00/BB/F9/wKgaomWXeQSAfh6AAAFOF4YmdO8191.jpg)
評論