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

Redis實(shí)現(xiàn)限流的三種方式分享
測(cè)試開發(fā)實(shí)踐:網(wǎng)關(guān)路由功能及測(cè)試

DAB Announcement高效測(cè)試方案及應(yīng)用分析

無人機(jī)測(cè)深的三種方法總結(jié)

評(píng)論