符合架構的測試
核心要點
- 微服務通常屬於跨功能且自治的團隊,該團隊負責微服務的實現、測試和發布。
- 在實現微服務架構時,不應該有獨立的測試階段。
- 每個人都要對產品的質量負責。
- 微服務集成的複雜性要求我們謹慎地決定合適的集成測試方式。
- 持續測試意味著要向左轉變以確保團隊保持自治,還要向右轉變以實現探索性和實驗性。
架構會對測試帶來重要的影響。測試單體系統的方式與測試松耦合系統的方式是不同的。我們以微服務作為松耦合系統的典型示例。下面將會看到,它們挑戰了我們之前對於測試的定義。
康威定律
Melvin Conway觀察到組織的結構會對它們所創造的產品帶來顯著的影響:「任何組織在設計一套系統時[……],所交付的設計方案在結構上都與該組織的溝通結構保持一致。」
康威定律說明公司的軟體架構通常會反應組織的結構。另一方面,我們如何組織團隊會對架構和測試方法帶來巨大的影響。
架構和組織結構之間的互相依賴也會反映到BAPO模型中,該模型假設在軟體工程中,需要解決四個關注點:業務(Business)、架構(Architecture)、過程(Process)和組織(Organization)。從根本上來說,這個理念是基於業務需求來定義架構。但是,正如Jan Bosch(2017)所言,大多數的公司並不符合BAPO,而是遵循OPAB,也就是以組織結構作為基礎來定義架構。
如果組織想要改變軟體產品的架構的話,那麼它的組織結構(包括測試如何組織)可能是一個推動者,也可能是一個障礙。讓我們看一下不同類型的組織結構:
- 面向功能的組織 能夠優化成本。這些組織一般會有層級的結構,結構中包含專家團隊,他們負責其功能領域。
- 面向市場的組織 能夠優化速度。這些組織一般會比較扁平化,具備跨功能和自治的團隊,他們負責實現和交付產品,不過這樣有可能會導致在整個組織範圍內產生冗餘。
- 面向矩陣的組織 試圖將面向功能和面向市場的理念結合起來。
關於這方面的更多信息,參見:Gene Kim(2016)。
測試微服務
像微服務這樣的松耦合架構該如何進行測試呢?
松耦合的系統遵循服務自治的原則,因為它的架構就是基於各個自治的組成部分分解而成的。
越來越多的組織在採用微服務,以便於提升團隊的自治性並加快應變的速度。微服務應用由小型、版本獨立且可擴展的服務組成,這些服務以客戶為中心,它們彼此之間以定義良好的介面通過標準協議進行通信。
微服務
- 是自治的並且真正松耦合,因為每個微服務都是與其他的微服務物理分離的。
- 只負責一項功能(功能分解)。
- 可以獨立部署和發布。
- 應該嵌入依賴,以確保集成點的數量是可管理的。
- 應該能夠通過自治性實現彈性和故障隔離。
這對測試意味著什麼呢?
如果我們面向領域並且針對每個業務功能進行垂直切分,那麼依然可以有分層的架構,但是層是次要的組織機制。自治的產品開發團隊負責實現、測試和交付業務功能:
微服務通常會伴隨著 DevOps :在敏捷和DevOps中,在開發階段開始之前,並沒有架構師定義整體架構的單獨設計階段。相反,架構會以更加聯合的方式來定義,跨越多個項目,並且被整個團隊所擁有。
那麼這些系統的測試方式又會發生什麼樣的變化呢?同樣,測試不會在一個單獨的測試階段來完成。與之相反,每個人都要為質量負責。
沒有獨立的測試階段:
DevOps和持續集成&持續交付(Continuous Integration & Continuous Delivery,CI & CD)解決了快速且高質量為客戶交付功能的需求。這意味著測試必須要提供快速和有意義的反饋。為了快速且有自信地發布版本,需要從 持續測試(Continuous Testing) 中得到立即的反饋:
- 所有的測試幾乎都要是自動化的。對於CI & CD來說,啟用持續測試是至關重要的,因為它提供了關於質量的及時反饋。同時,它能夠讓團隊快速掌握和應對。
- 但是,這並不意味著持續測試只與自動化測試相關。我們接下來將會看到,它是一個全面的方法,目的是得到質量的及時反饋:
圖片來源:Dan Ashby (2016)
測試並不是一個隔離的活動,而是集成到一組綜合的實踐中,以便於提升質量:「依然有很多的公司在努力改變流程以提升質量,從『測試或檢查質量』轉變到一開始就保證高質量,這要通過文化、設計、工藝以及領導力才能實現」(Ben Linders 2017)。
開發人員在確保高質量方面扮演了重要的角色,另外,軟體工藝原則也能促進質量的提升。軟體工藝指的是軟體開發過程中專業性:「工藝精湛的軟體意味著,不管應用多麼古老,開發人員都能很容易地理解。它的副作用眾所周知並且能夠得到控制。具備很高很可靠的測試覆蓋率,設計清晰簡潔,代碼能夠很好地表達業務語言」(Sandro Mancuso,2015)。
持續測試(通常)意味著向左轉和向右轉:
向左轉和向右轉是什麼意思呢?
測試通常是按照特定的順序執行的,從(左側的)單元測試開始,因為它們能夠提供快速的反饋,後續的測試則需要更長的時間來執行,但是它們能夠增加我們對候選釋放版本的自信心:
在這裡,有一種左轉的趨勢,那就是自動化單元和組件級別的測試,在持續集成&持續交付(CI & CD)管道中執行,這個管道是由產品開發團隊所擁有的。但是,這是有其成本的:考慮到集成場景的複雜性和動態性,集成測試會變得更加具有挑戰性。
如果我們要對比討論隔離狀態以及基於協作的測試,那麼很重要的一點就是要區分獨立性的(solitary)和社會性的(sociable)測試方式:
- 在獨立性的測試活動中,被測試的軟體單元是隔離的,要將協作者(上游依賴)替換為測試替代品(test doubles),比如mocks或stubs。
- 在社會性的測試活動中,被測試的軟體單元要與協作者一起進行測試。
按照測試金字塔的理念,微服務測試的關注點在於要有很多的單元測試以及一組全面的組件測試。微服務首先會彼此隔離地進行測試,然後進行少量的集成,最後是端到端測試。很多端到端測試通常被視為一種問題,因為它們的執行比單元和組件測試要耗費更長的時間,並且也會更加脆弱。但是,很有意思的一點在於,有一種關於測試金字塔理論對微服務測試的價值的爭議,以及如果關注單元和組件測試,並使用它們來替代集成測試是否依然是合理的(參見樣例:Cindy Sridharan 2017和André Schaffer 2018)。這是一個合法性的問題,因為如果微服務的集成是最具挑戰性的,那我們是否可以不要更多關注集成測試,而是更多的依賴社會化的測試?我認為,答案可以說是也可以說不是:如果微服務的嵌入式依賴沒有提供獨立的業務功能,那麼將微服務與這些依賴一起進行測試是非常有意義的。在微服務中,這種類型的社會化測試應該在與其他微服務的集成測試展開之前完成,其他的微服務會封裝別的業務功能。如果沒有足夠的單元和組件級別的測試,分析集成測試的故障會更加複雜。同時,除了傳統的集成測試以外,API以及契約集成測試也是非常重要的,因為它們有助於保證微服務協作管道之間能夠互相獨立。因此,在合適的測試等級進行測試是非常重要的。
另外一個方面也很重要:對於微服務來說,集成場景是複雜和動態的,要有多少集成測試才夠用呢?將更多的精力投入到測試中以及在生產環境中快速探查問題之間要有一個權衡。除了左轉之外,還有一個趨勢,那就是將測試與生產環境的部署和監控更加緊密地連接在一起。生產環境的核對實驗(controlled experiment)有助於快速識別問題並得到真實用戶的快速反饋。
不同類型的生產環境流量測試有何差異?
這意味著在測試方面還有向右轉的趨勢。
如前文所述,面向市場的組織針對速度進行了優化,在測試領域的右轉有助於完成他們的目標。作為持續實驗的一部分,可以進行探索和學習。藉助核對實驗,在現實中使用應用程序的時候,我們能夠得到客戶的反饋。
核對實驗也能支持彈性架構。正如我們在前面所討論的,微服務應該通過自治實現可靠性和故障隔離。但是什麼是彈性呢?「我們通常認為脆弱系統的對立面就是健壯的系統,因為脆弱的系統通常不會過多(換句話說,說不上喜歡或不喜歡)關注壓力。實際上,健壯的系統僅僅脆弱程度有所降低而已。脆弱系統真正的對立面是能夠從壓力中受益的系統。Nassim Taleb將這樣的系統稱為反脆弱(antifragile)的」(Dave Zwieback 2014, p. 3)。傳統的測試方式是在版本發布之前對系統進行測試,以確保穩定性。但是,這些測試能夠支撐健壯性,但是無法支撐系統的「反脆弱性」。有種不同的測試方式就是在生產環境中引入故障,運行主動可控的混亂(chaos)實驗。這種精心設計的混亂能夠指導產品開發團隊思考故障的容忍度和隔離故障的可能性。
總結
對於微服務這樣的松耦合系統,測試不應該在一個單獨的測試階段由專門的測試團隊來進行,而應該由跨職能的產品開發團隊來完成。在測試中,有一種向左的轉變,確保團隊能夠保持自治,同時還有一種向右的轉變,這種轉變強調的是探索性和實驗性。
持續測試(Continuous Testing),既包括CI & CD中的自動化測試,還包括實驗性和探索性的文化,它能夠保證快速且穩定地發布松耦合的服務。
參考文獻
- Ashby, Dan (10/2016): Continuous Testing in DevOps .
- Bosch, Jan (11/26/2017): Structure Eats Strategy .
- Conway, Melvin E. (1968): How do Committees Invent?
- Kim, Gene (11/16/2016): H ow to Design With Conway』s Law in Mind .
- Linders, Ben (2017): What Drives Quality: A Deep Dive into Software Quality with Practical Solutions for Delivering High-Quality Products. Ben Linders Publishing.
- Mancuso, Sandro (2015): The Software Craftsman. Professionalism, Pragmatism, Pride. Pearson Education.
- Schaffer, André (01/11/2018): Testing of Microservices .
- Sridharan, Cindy (12/30/2017): Testing Microservices, the sane way .
- Zwieback, Dave (2014): Antifragile Systems and Teams. O』Reilly Media.
關於作者
Stefan Friese 是 HERE 的測試與研發主管,目前在柏林工作。在當前的職位中,他帶領團隊為一些實時位置的Web服務來構建持續集成&交付的測試功能,這些服務託管在HERE雲平台上。Stefan有著14年的工作經驗,曾經擔任過測試主管、性能測試人員、軟體工程師以及質量工程師。你可以通過@y3key在twitter上關注Stefan的動態。
如果有任何疑問,歡迎添加qq群測試入門到大神 755431660 共同學習~
推薦閱讀:
※Docker、kubernetes、微服務、SpringBoot/Cloud...好亂!到底要不要學?
※IIS架構與HTTP請求處理流程
※如何構建一個較為通用的業務技術架構
※什麼是架構設計
※戰狼:業務高速增長,如何保證系統高可用