09-微服務接口:怎么用Mock解決混亂的調用關系


微服務下混亂的調用關系

開發團隊開始采用微服務架構開發系統的時候,我的測試團隊也開始同步學習對應的測試技術,我也像從前一樣,逐步封裝自己的測試框架,並且采用Postman和Python代碼,完成接口測試腳本的快速積累,同時引入了參數類,完成了Excel參數的封裝調用。

在開始的一些項目中,只要開發工程師提交了代碼倉庫主干的合並請求后,除去代碼的靜態掃描外,持續集成平台會自動調取一個開源的智能化單元測試框架,來完成單元測試,通過后它會自動部署被測系統,然后再執行測試腳本,這整個流程全部是流水線自動驅動完成的。

一般來說,開發工程師在開發前期就已經定義好了微服務接口,測試工程師和開發工程師幾乎是同步開始進行各自的開發任務。但是,這種和諧的工作場景很快就被蜘蛛網一樣的微服務調用關系給破壞了,幾乎所有的項目都會出現相互依賴的關系,比如說服務A依賴服務B,服務B依賴服務C,如下圖所示:

這種混亂主要體現在:

  • 當持續集成流水線部署服務A的時候,由於對應的開發工程師團隊也在做同步改造,導致測試環境的服務B不可用;

  • 由於服務B依賴服務C,而服務C還沒有開發完成,導致即使服務A和服務B都沒問題,但也沒有辦法完成服務A的接口測試。

其實這種服務A依賴服務B,服務B依賴服務C的依賴方式還算簡單,還有更多微服務隨着開發越來越復雜,服務之間的調用關系就像蜘蛛網一樣錯亂,讓你摸不清外部依賴到底有幾層,以及一個接口到底依賴了幾個外部接口。

這就導致了雖然被測系統已經開發完成,測試腳本也准備就緒,但是測試工作就是沒辦法進行的悲慘結局。面對這種局面,我當時心里確實很不舒服,因為自己做了那么多努力,到頭來卻被一個不是由自己負責的服務卡住了工作進度,這感覺就像是用盡了全身的力氣,卻一拳打到了棉花上,自己有再多的勁兒也沒處使。

Mock框架的抉擇:用什么實現服務B的替身

那作為測試工程師,面對這樣的情形,我們該怎么辦呢?

我當時想到的就是使用Mock服務。其實Mock服務是一個錯誤的說法,關於這一點我推薦你看一下Martin Flower的這篇叫做TestDouble的文章,一般我們將TestDouble服務叫做測試替身,但是如今的國內業界里,絕大部分人已經習慣了叫Mock服務,因此在這里我們也還是叫Mock服務。

針對混亂的調用關系,我的思路是:我的被測服務就是服務A,那么我不用管服務B是不是好用,我只要保障服務A能夠走完流程,就可以完成接口測試任務了。循着這個思路,我只要用Mock服務偽裝成服務B就萬事大吉了,我也不用再關心服務B到底調用了多少服務。

但是在選取Mock服務框架時,我又面臨着一個抉擇,那就是用什么來實現服務B的替身。現在可以實現Mock服務的框架特別多,但絕大部分都要求你有很好的代碼基礎,每做一個Mock服務其實就是做了一個簡單的服務B,不同的是,它不需要實現原有服務B負載的處理邏輯,只要能按服務B的處理邏輯給出對應返回就可以了。

因此,有些團隊也會把這樣的服務叫做擋板系統,這個名字很形象。也就是說,我給了Mock服務B的請求參數,它只要按照約定好的返回給我參數就可以了,至於一系列其它驗證或者微服務調用,都不在Mock服務的設計內,這就像你對着牆打乒乓球一樣,牆是你假設的對手,會把你打過去的球擋回來,而你要做的就是接住牆擋回給你的球。

那么,到底應該怎么選擇Mock服務框架呢?

首先,你要基於自己和團隊的技術棧來做選擇,這決定了你完成服務B替身的速度。你要知道,無論服務B的替身做得多么完美,它只是一個Mock,它存在的意義就是幫助你快速完成服務A的接口測試工作,因此,選擇一個學習成本低、上手快並且完全適合你自己技術棧的Mock框架,能讓你的測試工作事半功倍。

其次,你要讓寫好的Mock服務容易修改和維護。Mock服務就是一個在測試過程中替代服務B的替身,就和拍電影時的替身演員一樣,替身演員可能有好幾個,需要在不同地方拍攝不同的電影片段。Mock服務可能只有一個,也有可能有好幾個,為了不同的調用或者測試而存在。但是,Mock服務會隨着服務B的變化而變化,如果服務B的請求參數和返回參數有變化,那么Mock服務也要能快速完成修改,並且能馬上發揮作用。因此,一個非常容易維護的Mock服務框架,才更能馬上快速投入使用,快速發揮作用。

如果你的團隊技術基礎很好,開發能力很強,那么我建議你用對應語言的Mock框架,例如Java語言的Mockito框架和Python語言的mock框架

如果你的團隊技術基礎相對比較薄弱,那么我推薦你看看moco,這個框架在開發Mock服務的時候,提供了一種不需要任何編程語言的方式,你可以通過撰寫它約束的Json建立服務,並通過命令啟動對應的服務,這就可以快速開發和啟動運行你需要的Mock服務。

更重要的是,Json格式的數據文件可以獨立完成Mock的服務設計,而且Json的學習成本和Python語言相比,就如同小學一年級的數學和高中數學之間的難度差距一樣,就更別說和猶如高等數學的Java語言相比較了。如果你想詳細的學習moco,可以直接去它在Github上的項目空間,那里有詳細的使用說明和示例代碼。

我的Mock服務設計經驗

在選擇好Mock框架后,你就可以酣暢淋漓地完成各個外部依賴服務的解耦工作了,但是關於Mock服務,我還想告訴你一些我的設計經驗。

首先,簡單是第一要素。無論原服務B處理了多么復雜的業務流程,你在設計服務B的Mock服務時,只要關心服務B可以處理幾種類型的參數組合,對應的服務都會返回什么樣的參數就可以了。這樣你就能快速抓住Mock服務B的設計核心,也能快速完成Mock服務B的開發。

其次,處理速度比完美的Mock服務更重要。一個Mock服務要能按照原服務正確又快速地返回參數,你不需要把大量的時間都浪費在Mock服務的調用上,它只是用來輔助你完成接口測試的一個手段。你需要讓它像打在牆上的乒乓球一樣,一觸到牆面馬上就反彈回來;而不能把球打出后,需要去喝個茶或者坐下休息一會,才能收到反彈回來的球。

如果你的Mock服務很耗時,你在只有一個兩個服務時,可能影響還不是很明顯,但如果你同時有多個Mock服務,或者需要用Mock服務完成性能測試的時候,這就會變成一個很嚴重的問題,后續會引發強烈的“蝴蝶效應”,使得整個被測接口的響應速度越來越慢。因此你要建立一套快速的Mock服務,盡最大可能不讓Mock服務占據系統的調用時間。

最后,你的Mock服務要能輕量化啟動,並且容易銷毀。你要時刻注意,Mock服務只是一個輔助服務,因此,任何一個團隊都不希望啟動一個Mock服務需要等待5分鍾,或者需要100M的內存。它要能快速啟動、容易修改並且方便遷移。既然Mock服務的定位是輕量化的輔助服務,那么它也要容易銷毀,以便你在完成測試后,可以快速且便捷地釋放它所占據的資源。

總結

微服務現在已經鋪天蓋地而來,尤其在中台化戰略的推動下,業務中台服務的依賴關系會越來越復雜,並且隨着團隊內微服務數量越來越多,每個測試團隊面臨的被測系統都會是一團亂麻,很容易找不到頭緒。

為了解決由於微服務間相互依賴而導致的混亂的系統調用關系,我建議你盡快掌握一個Mock服務框架,這樣可以讓你在混亂中理清思路,快速進行接口測試,交付高質量的項目。

最后我要提醒你的是,選擇Mock的技術棧與選擇測試框架的技術棧還是有些區別的,在選擇Mock技術棧時,你重點要考慮的是學習成本,把學習成本降到最低,才是選擇Mock框架的首要關注點。而且你不只要關注自己的學習成本,也要關注你所在團隊的學習成本,因為現在每個項目都有可能需要Mock服務,這個時候,就要求每一個項目的測試工程師都具備自己獨立建設Mock服務的能力,在Mock服務的技術選型上,還是要以團隊整體的技術棧為基礎,以自己的技術為參考進行選型


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM