文/張圓冰
隨著軟件技術架構發展,軟件系統的復雜程度也越來越高。傳統的單體應用架構耦合度高,設計、開發、部署為一個整體的單元,部分更新都需要重新部署整個應用。隨著應用功能升級,維護、升級、新增功能都會變得越來越困難,很難以敏捷研發模式進行開發和發布,進而導致軟件功能升級效率低下。所以微服務架構應運而生。微服務的顆粒比較小,一個大型復雜軟件應用由多個微服務組成,每種服務只做一件事,是一種松耦合的能夠被獨立開發和部署的無狀態化服務(獨立擴展、升級和可替換),不同服務通過一些輕量級交互機制來通信,最終構建出實現完整功能的軟件系統。
微服務這種細粒度的特性,為功能升級帶來便利的同時,給軟件測試提出了較大的挑戰。主要體現在兩方面:
(1)微服務架構將服務拆分成數量眾多的接口,大量接口的快速迭代需要良好的自動化測試體系予以支撐;
(2)不同服務接口之間開發獨立,但又需要彼此通信,因此單接口的測試,如何避開外部接口變動的影響,也是需要思考的。本文主要就這兩方面問題進行了探索和實踐。

圖1:整體應用架構示意圖

圖2:微服務架構示意圖
微服務架構是相對傳統軟件架構而言的。傳統軟件架構可以看成一個完整的單元。一般由用戶界面,后臺服務端應用和數據庫三層結構組成。服務端應用是完整的,是一個單獨的的邏輯執行;數據庫是由許多表構成一個通用的、相互關聯的數據管理系統。應用服務程序接收客戶端輸入,計算處理后檢索并更新數據庫中數據。這是一種自然而然的構建系統的思路,所有的功能實現模塊都集合在一起,通過負載均衡將多個應用部署到多臺服務器上。傳統架構在長期以來的軟件架構設計中被廣泛使用,并獲得成功。整體應用架構示意圖如圖1所示。
但是,隨著軟件快速迭代要求提升,以及云部署技術的廣泛使用,整體應用程序面臨著變更應用程序的一小部分,卻要求整個應用重新構建和部署的問題。隨著時間的推移,很難再保持一個好的模塊化結構,使得一個模塊的變更很難不影響到其它模塊。所以,以服務為單元拆分整體架構,形成一個個單獨功能模塊,可以獨立部署與修改,即我們通常說的微服務架構逐漸出現并為一些行業先行者應用到軟件系統設計中來。微服務架構傾向圍繞業務功能的組織來分割服務,在這個功能模塊中涉及到的技術、數據存儲、用戶體驗等都劃歸到該微服務設計者需要考慮的范圍內。如圖2所示。
目前常見的微服務設計都是會采用一些分布式服務框架,這些框架從通信協議上分為兩種:公共標準的HTTP協議和基于私有的RPC調用協議。公共標準的HTTP協議有一些成熟的自動化測試工具可以使用,本文主要介紹使用RobotFramework工具設計實現的基于HTTP接口的微服務自動化測試框架。
Robot Framework(以下簡稱RF)最初是由 Nokia Networks 公司開發的一個開源自動化測試框架,框架基于 Python語言實現,包含豐富的測試工具及測試庫,同時具有很強的擴展性。RF框架通過集成不同的測試工具,可以進行各種自動化測試。微服務HTTP接口的測試,就是采用了RF內置的RequestsLibrary庫中,Post Request、Get Request等方法進行進一步設計和封裝。封裝時,為了適用于普遍的HTTP接口,將微服務接口IP,URL地址,POST方法傳遞的報文,HTTP報文header,以及身份驗證等信息作為參數開放。POST類型接口封裝的關鍵字示例如圖3所示。

圖3:POST類型的HTTP接口調用封裝

圖4:用例中使用此關鍵字
在組織自動化用例時,采用數據與關鍵字分離的策略。將使用到的參數和報文體放在參數文件中,在用例中引用此參數文件獲取參數值,用例中不展示參數正文,只見參數名稱。這樣組織用例的好處在于,只需要維護一份參數文件,如果接口定義或報文正文有變化,可以在文件中直接修改即可,無需大量修改用例。“&{params}”“&{interface}”都是字典類型的數據存儲方式,可存儲多個IP、URL鏈接等;${data}是定義在參數文件中的報文正文。按照這種思路封裝關鍵字和組織自動化用例,用例步驟基本都固定,便于測試人員大規模構建用例。用例如圖4所示。
由于微服務架構中彼此服務之間是獨立的,可自行組織開發、測試、上線等活動,但是彼此之間又存在通信調用關系。一個微服務接口開發過程中,某些功能的測試可能需要與其他服務通信,但其他服務可能不具備測試條件,所以微服務測試中需要用到Mock的思想。Mock是指在測試中,測試系統通過構造一系列符合預定義規則的模擬對象(Mock Object)來與被測試單元進行交互,從而判斷被測試單元在正常邏輯,異常邏輯或壓力情況下能夠正常工作,返回預期的輸出結果。Mock的使用需要配合一些已有工具,定義被調用方的模擬服務名、URL等,再配置相應的匹配規則和返回數據即可。Mock規則定義需要注意的是,不同規則需要設計唯一的關鍵字,當報文中具有這一關鍵字時會匹配到這個規則對應的返回數據,如關鍵字不唯一則會出現不同報文都返回同一數據的情況,造成測試結果的失真。Mock使用時需要在被測服務內部,配置模擬對象信息,在調用時,只要發送報文匹配到了Mock中的規則,即可獲取到返回報文,達到忽略其他服務真實情況即可完成測試的目的,便于自動化測試用例的順利執行。
本文在對現行通用的軟件系統微服務架構學習的基礎上,基于RobotFramework工具設計了用于微服務測試的自動化測試框架,并結合Mock測試思想,在微服務互相調用時采用了模擬報文返回的方式,使得自動化測試能獨立執行,不受外部服務干擾,提高了測試效率。目前此自動化框架已經用于基于HTTP接口的微服務測試中,為功能的快速迭代起到了保障作用。