在過去幾年中,微服務悄然卻堅定地在擁擠的軟體架構市場上占據了一席之地。與傳統單一整體式架構有所不同,微服務架構並不是將應用作為單體來構建的。雖然單一整體式架構本來是很可靠的,但相關的問題越來越多,特別是在更多應用採用雲端部署的方式之後。微服務架構屬於模塊化的結構,它並非是由拼插在一起的組件堆成,而是 ...
在過去幾年中,微服務悄然卻堅定地在擁擠的軟體架構市場上占據了一席之地。與傳統單一整體式架構有所不同,微服務架構並不是將應用作為單體來構建的。雖然單一整體式架構本來是很可靠的,但相關的問題越來越多,特別是在更多應用採用雲端部署的方式之後。微服務架構屬於模塊化的結構,它並非是由拼插在一起的組件堆成,而是將軟體分解打散為不同的服務,從而形成組件化結構。因此在微服務架構中,整個應用就像一套彼此獨立、可部署、可伸縮的服務,甚至為使用不同語言編寫不同服務提供了靈活性。此外,這種方式也有助於跨團隊間的並行開發。
很明顯,隨著業界轉向微服務架構,適用於單一整體式架構的測試方案也需要轉變。考慮到以微服務構建的應用在功能和性能上都更出眾,微服務測試也必須覆蓋各個層面以及層面間服務,同時還要保持輕量級。然而,由於微服務開發本質上是分散式的,相關測試也經常會有很大挑戰,下麵列出了其中一些:
如果測試團隊傾向使用Web API測試工具——這類工具常在SOA測試中使用,在微服務測試中就會產生問題。由於在微服務架構中,各個服務由不同團隊開發,想要在測試時及時提供所有服務會頗具挑戰性;
在測試生命周期的各個點上,確定恰當的測試量也是一種挑戰;
測試與數據驗證中的提取日誌十分複雜;
考慮到開發的敏捷與非集成性,提供專門的測試環境也是一種挑戰。
Mike Cohn的測試金字塔(Testing Pyramid)在測試方案制定時非常有用,可以協助確定所需的測試量。根據這個金字塔,在測試時採用自下而上的方法,並將各個階段所需的自動化工作量納入考量,會有助於解決上面提到的那些挑戰。
單元測試
單元測試的範圍局限在服務內部,它是圍繞著一組相關聯的案例編寫的。由於單元測試的數量較多,理論上應當是以自動化方式執行的。在微服務中執行單元測試時,必須將協作型單元測試(Sociable unit testing)與孤立型單元測試(Solitary unit testing)相結合,通過觀察其狀態變化來檢查模塊行為,並查看對象以及其依賴項之間的交互情況。然而,測試者需要確保在單元測試中,當單元“行為”受限時,“實現”不會受到測試的限制——可以通過不斷將單元測試的價值與維護成本/實現受限的成本相對比來做到這一點。
集成測試:
儘管單獨測試模塊非常重要,但測試各個模塊能否正確交互,並測試其作為子系統的交互性以查看介面的缺陷也同樣重要,這項工作可以通過集成測試來完成。集成測試的目的在於:通過集成模塊檢查路徑暢通與否,來確認模塊與外部組件的交互情況。執行“網關集成測試”與“持續集成測試”能確保在找到外部組件間的邏輯回歸與斷裂之處時迅速獲得反饋,從而有助於評估各個單獨模塊中所含邏輯的正確性。
組件測試:
微服務中的組件測試要求:使用測試替代與內部API端點,通過替換外部協作的組件,獨立對各個組件執行測試。組件測試提供給測試者一個受控的測試環境,並幫助他們從消費者角度引導測試,允許綜合測試,提高測試的執行次數,並通過儘量減少可移動部件而降低整體構件的複雜性。組件測試也能確認微服務的網路配置是否正確,以及是否能夠對網路請求進行處理。
契約測試:
上述三種測試對模塊提供了高測試覆蓋率,但並未測試到外部依賴是否支持端對端的業務流。而契約測試會測試外部服務的邊界,以查看服務調用的輸入/輸出,並測試該服務能否符合契約預期。將所有的消費者契約測試結果集合起來,有助於維護者在需要時對服務作出變更(不影響消費者),並十分有助於在定義新服務提供支持。
端對端測試:
除了測試服務之外,測試者還需要確保無論使用何種架構構建,應用都必須達到業務目標,同時我們還要測試集成系統運行的完整性。因此在微服務測試方案中,端對端測試占據了重要的角色。除此之外,考慮到在微服務架構中有一些執行相同行為的可移動部件,端對端測試時需要找出覆蓋缺口,並確保在架構重構時業務功能不會受到影響。
結論:
微服務中的測試必須在顆粒度上更加細緻,同時避免因過於敏感而浪費時間。要想制定強大的測試方案,測試者需要恰當定義服務、明確指定界限。考慮到軟體行業正在向微服務傾斜,這些應用的測試者可能得在服務級別上對流程與測試的實施方式直接進行修改。這樣一來,他們不僅能夠正確地測試各個組件,也能在集成應用與交付優質產品時有更多時間集中精力執行端對端測試。