Categories
程式開發

微服務測試—六份案例研究和技術組合(第三部分)


本文要點

  • 測試微服務時,要考慮的一個重要因素是如何管理關聯的依賴項。有很多種技術可以用來解耦依賴項,但是它們都有一些權衡,開發/QA團隊必須意識到這一點。
  • 架構師、開發人員和QA團隊必須共同努力,以理解和指定測試目標、上下文和當前的約束條件。
  • 制訂一套全面的測試方法通常需要實施多種測試策略。必須仔細選擇這些策略,以避免重複工作或增加測試套件的偶發複雜性。
  • 契約測試是驗證服務之間交互的一種有價值的方法。可以將契約測試與精心挑選,數量有限的端到端測試相結合,以驗證完整的業務流程。
  • Mock和服務虛擬化有助於在測試過程中解耦組件。應當精心確保這些測試替身處於正確狀態,並與當前關聯實現的最新版本保持同步。

這是《微服務測試》系列的第三篇文章。另請參見《微服務測試的 12 項實用技術(第一部分)》和《微服務測試的 12 項實用技術(第二部分)》。

我們Traffic Parrot最近與六家公司展開了合作,這些公司是眾多行業領域的代表,並且在應用微服務方面有著成熟的經歷。這些公司應用了我們在本系列第一部分中描述,並在第二部分中評估的一系列測試技術的組合,這些技術使你可以在測試微服務時管理從屬組件。在第三部分中,我們將展示對應的案例研究,介紹這六家公司是怎樣應用這些技術的。

首先我們介紹三份案例研究,這些案例中公司將測試技術的組合用作整體解決方案。後三份案例研究中,企業使用單一技術來解決特定問題。

技術組合:美國保險業初創公司

架構

Greenfield微服務取代了最近構建的單體架構。

技術棧

Go、Python、NodeJS、gRPC、Protocol Buffers、Docker和Kubernetes。

任務優先級

快速交付;將在首次生產發布後重構發布流程。

使用的測試技術

  • 技術#1——使用另一個微服務的測試實例測試你的微服務(端到端測試)
  • 技術#6——Mocks(進程內)
  • 技術#9——服務虛擬化(通過本地/遠程)
  • 技術#11 —測試容器

契約管理

  • 團隊使用API​​​​ mocks在彼此之間傳達契約的語法和語義。
  • API mocks定義了自動測試的契約快照,以確保它們與最新的協議規範保持同步。

要點

  • 使用了gRPC協議API mocks來允許團隊並行工作。
  • 使用自動化測試來確保API mocks不會過時。

這家初創公司有兩個團隊,當時他們在開發一組共三個新的微服務,必須在兩個月內交付。這些微服務正在替換已棄用的一個單體架構的一部分內容。團隊決定使用單元測試來測試Go微服務的內部組件,這些單元測試使用了進程內mocks,基於GoMock框架實現。他們使用組件級集成測試來測試與數據庫的交互,該測試使用測試容器數據庫來避免依賴數據庫的共享實例。

為了管理團隊之間的契約並允許團隊並行工作,他們決定使用API​​​​生產者創建並與API消費者共享的API mocks。他們使用API​​ mocking工具創建了gRPC API服務mocks。

他們還在預生產環境中使用了一些手動端到端測試,以確保在沒有足夠的自動化測試的情況下,微服務也能協同工作。他們將在第一個期限之後填補自動化測試中的空白。

由於這是一個必須按時投入生產的綠地項目(新開發的項目),因此公司決定不對微服務API進行版本控制。相反,每次發佈時他們將所有內容一起發佈到生產環境(通常稱為快照版本)。他們考慮到了服務的停機時間,以及與之關聯的,面向客戶的組件出現的小幅度功能退化,這些問題已事先通知客戶。在發布第一個產品之後,他們開始對API進行語義版本化。這使他們能夠更好地管理API更改,以實現向後兼容性並為客戶提升正常運行時間。

他們在早期就遇到了另一個有趣的問題,那就是API mocks每天都會過時,因為API確實每天都在變化。這些更改通常不會向後兼容,因為開發人員正在重構協議文件以反映正在快速進化的領域模型,當時他們尚未明確定義這一模型。這種狀況是綠地項目普遍所有的特徵,其中項目團隊使用迭代方法為客戶交付價值。為了按時完成任務,公司決定同時向mock和真實的微服務發出請求來測試API mocks。他們將兩者的響應與該公司專屬的自定義格式所定義的”預期請求/響應對”的契約定義進行了比較。這樣,與契約文件中定義的預期行為的最新定義比較後,API mocks和真實服務就可以被證明是最新狀態了。

技術組合:西班牙電子商務公司

架構

從擁有十年曆史的單體式服務器轉向微服務。

技術棧

Java、HTTP REST、gRPC、protocols、JMS、IBM MQ、Docker和OpenShift。

任務優先級

採用API優先方法,以允許並行工作和解耦團隊。在公司的3,000名開發人員中大規模採用微服務。

使用的測試技術

  • 技術#1——使用另一個微服務的測試實例測試你的微服務(端到端測試)
  • 技術#6——Mocks(進程內)
  • 技術#9——服務虛擬化(通過本地/遠程)
  • 技術#11——測試容器

契約管理

  • 團隊使用API​​​​ mocks在彼此之間傳達契約的語法和語義。
  • 行為驅動開發(BDD)API測試,還可以驗證API mock交互。
  • 這些API設計為始終向後兼容。

要點

  • 允許團隊使用API​​​​ mocks實現的API優先方法來並行工作。
  • 開發人員根據OpenAPI和協議規範創建了mocks。

這家公司決定從單體架構遷移到更自治的團隊組合和微服務上。在轉型過程中,他們決定採用推薦的良好實踐,而不是將特定的技術和解決方案強加給團隊。

團隊架構師負責收集開發人員要使用的技術、指南和工具。他們還負責創建一種架構,通過復用成熟的技術、工具和組件來最大程度地減少浪費。

開發人員編寫了JUnitTestNG集成測試,並使用API​​​​ mocking工具mock了從屬組件。他們還編寫了Cucumber/GherkinBDDAPI驗收測試來捕獲業務需求(他們稱其為“契約測試”),使用了微服務的Docker映像和稱為Traffic Parrot的API mocking工具的Docker映像。 BDD測試通過驗證API mocks上的交互來驗證微服務API和其與從屬組件的交互。這樣,BDD測試通過斷言和驗證來驗證微服務API請求和響應,以及它與從屬組件的所有通信。

該公司使用JMeter來創建性能測試。 JMeter測試可以測試單個微服務,並使用真實依賴項(例如微服務和舊的單體組件)的API mocks替換從屬組件。他們使用的一種技術是在API mocks上配置響應時間,並觀察增加的延遲對所調用服務的影響。

所有的單元、驗收和性能測試都在Bamboo持續交付管道中進行。

這家公司創建API mocks的方式很有趣。他們使用了兩種方式。

如果開發人員想要消費的API已經存在,他們會記錄請求和響應從而創建API mocks。開發人員首先在他們的計算機上創建一個新測試。然後,他們運行測試並記錄測試內容從而創建API mocks。他們將測試和mocks提交給Git中的微服務項目。在QA管道(在每次提交時啟動以檢查產品質量的管道)中,他們啟動了一個Docker容器,該容器運行API mocking工具並從微服務項目中加載mock定義。

如果微服務要消費的API尚不存在,則開發人員將根據HTTP REST API的OpenAPI規範創建API mocks,或根據gRPC API的協議文件創建API mocks

每當開發人員在測試套件中需要Cassandra數據庫時,他們就會運行Cassandra數據庫測試容器。這樣做的好處是不必依賴數據庫的中心化副本。他們使用自定義的Cassandra配置構建了自己的Docker映像。

他們還開發並運行自動化的端到端煙霧測試。這是測試微服務之間契約的技術之一,它能確保微服務組可以很好地協同工作。端到端測試套件的存在是有道理的,因為它不僅測試了在BDD測試中測試的契約生產者方,而且還測試了消費者方,因此提供了更多的可信度。架構師會監視端到端測試的數量。他們將端到端測試套件的複雜性保持在不會拖累發布流程或日常開發活動的水平。

技術組合:英國媒體公司

架構

在生產環境中已經有超過100種微服務,這些微服務運行在具備手動配置硬件的環境中。

技術棧

Java、HTTP REST、Docker和Kubernetes。

任務優先級

遷移至雲(內部Kubernetes集群)。從運營團隊管理的硬件遷移到Kubernetes集群上,後者由自治功能團隊管理,從而降低基礎架構成本並縮短面市時間。通過引入零宕機時間版本,將正常運行時間從99.5%提高到99.95%。

使用的測試技術

  • 技術#1——使用另一個微服務的測試實例測試你的微服務(在早期使用其他微服務進行手動探索性測試)
  • 技術#3——測試具有第三方依賴項的微服務(第三方的英國媒體基礎設施測試API)
  • 技術#5——測試具有非軟件(硬件)依賴項(網絡硬件)的微服務
  • 技術#6——Mocks(進程內)
  • 技術#9——服務虛擬化(通過第三方服務和其他微服務的本地/遠程API mocks)
  • 技術#11——測試容器(Oracle數據庫測試容器、API mocks測試容器和從屬微服務測試容器)

契約管理

  • 消費者驅動的契約以及集群中其他微服務的契約測試。
  • 第三方API每契約的窄集成測試。
  • 無回歸端到端測試。
  • BDD API測試還可以驗證API mocks交互。
  • 這些API向後和向前兼容(版本兼容性n±1)。

要點

  • 使用了消費者驅動的契約和消費者驅動的契約測試、BDD API測試以及API版本管理取代端到端測試。

這家公司現有一個包含100多個微服務的技術棧,主要使用自動化BDD端到端測試,但是它們的維護成本很高,因為開發人員需要花費大量時間來編寫和調試測試套件。由於被測系統的複雜性導致測試不夠穩定,所以開發人員經常會感到沮喪,從而導致許多不確定的故障點。這些測試還使他們無法做到按需發布新功能,因為這些測試需要花費幾個小時才能運行完畢。他們意識到,這套複雜的測試套件花費的時間太久了,並且放棄它的成本也太高了。有關端到端測試問題的更多詳細信息,請參閱Steve Smith撰寫的”被認為有害的端到端測試“。

吸取了這些教訓後,該公司決定不在其正在研究的新產品上實施端到端測試。這一產品將在新的內部Kubernetes集群上運行,並儘量減少端到端測試的使用,而應用新的契約管理技術。

為了針對新的微服務之間的契約以及整個產品行為來提升信心,他們使用的主要方法是以消費者驅動的方式設計契約。公司選擇使用Pact-JVM來測試消費者驅動的契約。公司中的大多數團隊是首次接觸消費者驅動的契約,但他們很快就掌握了這種方法。

他們用來改善微服務的另一項技術是在每個功能團隊中配備一名人工測試員。這名測試員將針對每個新用戶故事進行手動探索性測試。測試時,這名測試員將在自己的計算機上使用Docker測試容器運行微服務,有時還會與其他微服務一起運行。

開發人員決定基於清潔架構的理念來實現某些微服務,這需要使用進程內mocking,這個案例中他們使用的是Mockito

作為Docker測試容器運行的API mocks被廣泛用於mocking第三方的網絡硬件和棧中的其他微服務。

當在TeamCity構建內部運行時,BDD驗收測試使用WireMock進行API mocking。手動測試人員使用具有Web用戶界面的API mocking工具進行探索性測試。這種方法簡化了設置測試場景和測試微服務的工作。

解決特定問題:美國鐵路公司

問題:

遷移到為自治團隊提供的新CI/CD管道基礎架構,需要一種服務虛擬化工具,該工具可以在管道內部運行,而不必使用共享環境。

解決問題的技術:

技術#11——測試容器(將API mocks作為Docker測試容器運行)

要點:

使用按需API-mock Docker測試容器來避免依賴共享的服務虛擬化基礎架構。

這家公司決定從單體架構過渡到微服務架構上。在轉型過程中,他們推動的一項主要變革是新的CI /CD管道基礎設施。

負責設計管道架構的架構師希望使用在共享環境中部署的服務虛擬化。這樣做的原因是這家公司已經有了適當的解決方案。虛擬服務已在團隊之間共享,並且CI/CD會構建在現有的單體架構中。

經過仔細考慮,架構師意識到在新的微服務世界中,使用由眾多管道、開發人員和測試人員共享的服務虛擬化環境效果會適得其反。公司轉向微服務的原因之一就是讓功能團隊彼此獨立地工作。依靠由中心化的團隊管理的共享服務虛擬化環境並不會幫助他們實現這一目標。此外,任何共享環境都是一個單故障點,他們希望避免這種情況。

架構師決定,他們將使用API​​​​ mocks而不是共享的服務虛擬化環境,這些mocks將作為構建作業的一部分來部署。他設計了一種完全分佈式的部署方法,其中API mocks會按需部署。一個Jenkins構建將在測試套件之前啟動API-mock Docker測試容器並在OpenShift中運行。構建完成後,這些Docker容器將被拆除。

解決特定問題:以色列電子商務創業公司

問題:

將自動化API和第三方集成測試引入之前沒有開發人員接觸過它們的環境。

解決該問題的技術:

技術#9——服務虛擬化(使用第三方API虛擬服務的在線/遠​​程服務,前者由使用現成服務虛擬化工具創建的數據庫支持)

要點:

使用第三方API服務虛擬化工具創建由數據庫支持的虛擬服務,以加快剛開始接觸自動集成測試的開發人員的上手速度。

這家初創公司正在向市場推出新產品。開發人員正在添加新功能,但沒做過自動API或第三方集成測試。他們必須快速發布新功能,因此沒有多大空間來更改現有的開發流程。

QA自動化負責人在Jest中開發了API和集成測試框架。他使用了以前在許多項目中使用過的現成的商業服務虛擬化工具,從而創建了替代第三方API的虛擬服務。

該工具部署在了共享環境中,因為他相信這能讓他對新測試方法的應用擁有更多控制權。每個單獨的虛擬服務都由一個包含HTTP請求-響應映射數據的數據庫表支持。他決定允許通過數據庫設置虛擬服務,因為開發人員已經習慣在數據庫中設置測試數據。他選擇了開發人員比較熟悉的數據庫MongoDB。

這是向這家創業公司的開發人員介紹各種類型的自動化API和集成測試的第一步。這位負責人認為,開發人員可以輕鬆掌握數據庫驅動的虛擬服務。每人幾個小時的入門時間就足以讓開發人員開始編寫他們的第一個自動集成測試。

解決特定問題:美國商品經銷商

問題:

將亞馬遜簡單隊列服務(Simple Queue Service,SQS)隊列引入技術棧時,必須驗證是否已將正確的消息發送到正確的隊列,從而導致了手動測試問題。它還影響了自動化測試工作的成果。

解決問題的技術:

技術#8——服務虛擬化(通過亞馬遜SQS模擬器本地/遠程進行)

要點:

使用亞馬遜SQS模擬器可以在測試時無需訪問實際的SQS實例。

公司將亞馬遜AWS組件引入他們的架構。不幸的是,組織中的開發和測試團隊沒有協作機制,因此測試團隊要手動工作,而來自開發團隊的幫助卻很少。這意味著測試團隊無法使用可幫助他們測試產品的工具。他們總是落後於開發團隊,趕不上進度,還要在周末加班。最重要的是,他們被要求引入自動化測試,以逐漸開始擺脫手動回歸測試。

其中一項技術挑戰是使用亞馬遜SQS隊列手動並自動進行集成測試。為此,他們使用了帶有用戶界面的亞馬遜SQS模擬器,這使他們可以模擬有狀態的SQS隊列,從而繼續進行手動測試。他們使用模擬器的用戶界面來檢查隊列中的消息,以手動驗證請求消息。在它的幫助下,他們還開始使用SQS模擬器的API引入與SQS集成的自動化測試。

下一步

這裡描述的案例研究只是這些組織中發生的事件的一個縮影。我們主要研究團隊在測試時如何管理從屬組件,並特別選擇了這六份案例研究,因為它們代表了截然不同的方法。它們展示了團隊如何根據環境和團隊與任務相關的熟練程度來使用不同的技術。

我們很想听到讀者的反饋和故事分享。在第一和第二部分中提到的技術中,你們見過有哪些實踐案例呢?我們也非常希望聽到你對第三部分中介紹的這些案例的評價,說說你們是否贊成他們的測試方法和技術選擇。

請在文章下方發表評論,或通過LinkedIn或Twitter與我們聯繫。

如果你有任何關於特定項目的問題或疑問,請與作者聯繫:CEO Wojciech Bulaty,郵箱:[email protected]或@WojciechBulaty;技術主管Liam Williams,郵箱:[email protected]或@theangrydev_。

作者介紹:

Wojciech Bulaty是敏捷軟件開發和測試架構專家。他將自己十餘年的一線編程和領導經驗用在了敏捷、自動化、XP、TDD、BDD、結對編程和簡潔編碼領域的文章寫作中。他最近的成果是Traffic Parrot,其中他通過提供API mocking和服務虛擬化工具來幫助使用微服務的團隊加速交付、提高質量並縮短產品面市時間。

Liam Williams是一位自動化專家,致力於通過高質量的軟件解決方案來改進容易出錯的手動流程。他是開源貢獻者,並且是許多小型庫的作者。最近他加入了Traffic Parrot的團隊,進而將注意力轉向了在轉型現代微服務架構時改善測試體驗的問題。

本文是《微服務測試》系列文章的第三篇。另請參見《微服務測試的 12 項實用技術(第一部分)》和《微服務測試的 12 項實用技術(第二部分)》。

原文鏈接

Testing Microservices: 6 Case Studies With a Combination of Testing Techniques – Part 3