1. 程式人生 > >CODING DevOps 系列第五課:微服務測試——微服務下展開體系化的微服務測試

CODING DevOps 系列第五課:微服務測試——微服務下展開體系化的微服務測試

## 微服務測試的痛點與挑戰 這張圖可以形象地展示單體服務和微服務的對比,單體應用就像左邊巨大的集裝箱,軟體模組和應用都包括其中;而微服務就像是由一個小集裝箱組成,微小的服務組成一個龐大、完整的系統。單體服務是一個大而全的應用體,而微服務由拆分成出來的很多小服務來組成一個龐大而完整的系統。 ![1](https://s1.ax1x.com/2020/06/18/Nni5gf.jpg) 微服務是一種架構模式,是面向服務型架構 SOA 的一種變體,提倡將單一應用程式逐漸還原劃分成小的服務,服務間互相協調、互相配合,為使用者提供最終價值。微服務架構風格就是一些小而自治的服務協同工作形成鬆耦合的系統。另外,我們需要儘量避免一個統一的、集中式的服務管理機制,對具體的一個服務而言,應該根據上下文選擇合適的語言工具對其進行構建。 結合下方的這張圖,我們可以理解微服務構建的核心其實是中間領域的業務邏輯,圍繞著這個領域業務邏輯,會有一些微服務去進行拆分構建。 ![2](https://i.loli.net/2020/06/18/hVKExfZko64iJnm.jpg) 微服務具有專注、自治、獨立程序、獨立部署和技術異構的特點,即每個服務只限定於特定的業務而專注做一件事情,每個服務承擔的是單一職責,但是它也需要達到一定規模能夠完整的處理特定的領域業務。很多人都會被微服務的“微”這個詞所誤導,認為微服務就是要拆分的越小越好。但是其實為了“微”而將同一領域的業務拆分到不同的服務,只會徒勞增加軟體的複雜度和維護困難。 我們可以圍繞應用的業務能力進行分組,每個小組的開發組人員開發微服務的技術可以不受限制。每個服務小組可以使用不同的技術架構和儲存技術,有針對性地解決一些效能瓶頸問題。每個服務是互相獨立部署互不影響的,這樣的話我們可以實現獨立打包、獨立測試和獨立附屬,減少部署時間,提升研發效率。 微服務架構測試具有三個痛點:一、如何測試微服務的外部依賴是否正常;二、如何在微服務架構下驗證系統的整個功能是否符合預期;三、這麼多微服務的部署和測試,應如何開展。按照以上痛點我們可以看到,微服務測試是一種驗證成本高、結果不穩定、反饋週期長的測試。 ## 測試金字塔 測試金字塔其實是一種方法論,解決微服務測試的關鍵在於將微服務的測試按照不同的力度來分組。測試金字塔的概念由麥克科恩首先提出。測試是分層次的,我們看到圖片左邊,這個金字塔被分為三個層次,從下往上分別是單元測試、服務測試、介面測試,從下往上測試的執行速度是逐漸減慢的,外物依賴或者服務間的依賴從下到上會依賴更多。這個測試金字塔的另外一個重要特徵是,從下往上對每一層的測試程式碼是逐層減少的。下方應該寫一些小而快的測試,往上應該編寫一些粗粒度的測試,編寫更少的高層次測試。 ![3](https://i.loli.net/2020/06/18/eQlICW1smN9vT6L.jpg) 然而實際中如果以這個金字塔圖來作為指導,會過於籠統簡單,所以我們會採用右邊的分為四層的測試金字塔來做內部測試的指導思想。底層是單元測試,在這之上是整合測試,再往上是端到端的測試,頂層是探索測試。 作為開發人員或測試人員,應該關注金字塔的哪些部分呢?微服務開發人員應更多關注位於塔基底部的單元測試與整合測試。在這兩層需要開發人員編寫一定量的測試程式碼來保證覆蓋,應該寫許多小而快的單元測試覆蓋絕大部分的業務場景,再寫一定的粗粒度的整合測試,來測試重要系統之間外部依賴的互動是否正常。測試人員和質量保證人員應更多關注金字塔上面兩層,測試人員可以依據 BDD 的規範來編寫測試用例,用於校驗系統功能的互動是否正常,還可以用非常規的手段進行破壞性的探索測試。 單元測試是測試金字塔的底基,它的定義沒有標準答案。從程式設計角度來看,在函式式語言中我們可以認為一個函式是一個單元,在面向物件的語言中一個方法或者一個類可以表示一個單元。單元測試具有能夠及時發現 bug、利於重構、保證程式碼質量的優勢,我們系統中需要編寫得最多的其實就是單元測試。 ![4](https://i.loli.net/2020/06/18/4hutYcCgWOeQ68V.jpg) 微服務的測試一般是對入棧介面卡、業務邏輯和出棧介面卡這三部分進行測試。入棧介面卡測試的是 Controller API 是否正確;業務邏輯部分測試 Service 業務邏輯是否正確,而出棧介面卡部分測試的是 SQL 邏輯是否正確。單元測試一般會遵循一個通用的 3A 結構:Arrange,Act,Assert,這樣寫出來的程式碼更有閱讀性和表達力。 在微服務架構下我們所理解的整合測試是測試應用與外部依賴的整合。第三方外部服務依賴主要有兩種類:第一種是微服務會依賴第三方系統的服務;第二種是系統內部的微服務與微服務之間,一種服務可能會依賴另一種微服務來實現自身邏輯。對應這兩種情況會有不同的策略,第一種策略是準備真實的外部服務的依賴,第二種是使用測試替身隔絕外部依賴。進行整合測試的時候我們通常會使用一些,依賴第三方服務的話會採用 WireMock 或者 mountebank,而微服務之間的依賴呼叫會使用 Spring-Cloud-Contract 或者 Pact。 微服務之間的測試會使用契約測試,服務之間的介面文件就是一個契約。契約測試可以解決聯調成本過高,介面變動把控困難,契約變化時提供一種可立即被服務端和消費端發現的方式,這三種痛點。契約測試的提供者指微服務介面的提供者,消費者指微服務介面的消費者。契約檔案是微服務提供者和消費者共同定義的介面規範,包括介面的訪問路徑和輸出資料。 CDC 的核心思想在於從消費者業務實現的角度出發,由消費者自己定義需要的測試資料格式以及互動細節,並驅動生成一份消費者契約。然後生產者根據契約來實現自己的邏輯,並在服務提供者端進行測試驗證。契約文件應該被轉換成一個存根。生產者會根據契約編寫契約驗證測試,契約驗證測試通過會將契約檔案轉換為存根,存根會被消費者引用,契約的修改會導致任意一方測試的失敗。這樣的話可以保證契約被消費者和生產者共同遵守。 契約測試適用於微服務介面的消費者和提供者由不同的團隊維護,或提供者介面被多個消費者消費這樣的場景中。 端到端測試主要用於驗證工作流程中的所有流程,以檢查一切是否按照預期工作,確保系統以統一的方式工作,從而滿足業務需求。端到端測試的難點在於安裝和配置相關依賴,測試資料的自動準備二號服務的自動部署。 ## 微服務測試藍圖 ![5](https://i.loli.net/2020/06/18/ZT4tVaJobUBhL1k.jpg) 做微服務測試需要做 TDD,也就是測試在先,編碼在後的開發實踐。有別於以往的先編碼、後測試的開發過程,而是在程式設計之前,先寫測試指令碼或設計測試用例。TDD 可以增加開發人員程式碼質量的信心,有利於程式碼設計和重構,以及快速迭代和持續交付。 微服務測試推進主要分為四步:第一步是工具,依照微服務測試層次,階段選擇合適的測試框架與工具;第二步是依據測試金字塔制定規範,貫穿生命週期始終,明確開發、測試人員的職責;第三步是自動化,貫穿 CI、CD 流程,與 DevOps 的融合;第四步是測試平臺搭建,以容器化技術搭建測試平臺,以 namespace 隔離不同測試環境。 [點選觀看完整課程視訊](https://cloud.tencent.com/edu/learning/li