2017-08-18 50 views
1

假設我們有一個CreditCardService微服務,它依賴於使用JSON進行通信的ThreeDSecureService微服務。微服務合同的自動化測試?

ThreeDSecureService的API(或甚至實施)的微小變化可能會悄悄地破壞CreditCardService(和其他潛在客戶端)。所以,我們希望自動化測試。

我看到兩個有缺陷的方法,並且想知道如何改進。

  1. 在ThreeDSecureService.Tests中進行集成測試。

隨附的ThreeDSecureService測試項目可以通過固定的JSON輸入進行集成測試。僞裝任何依賴關係,它可以運行一個完全的輸入調用,確認服務吞下輸入。

這裏的問題是,如果有人未能意識到他們的變化會如何破壞客戶端,他們幾乎可以「修復」測試來匹配他們的變化。

  1. CreditCardService.Tests中的集成測試。

客戶端是實際上想要測試有關ThreeDSecureService預期輸入的斷言的人。但是,這需要客戶端解決方案包含ThreeDSecureService項目以及它所依賴的任何項目。這會否定我們從使用微服務中獲得的許多優勢!

我們如何在不破壞我們從使用微服務中獲得的鬆散耦合的情況下從客戶端斷言(維護依賴關係)?

+1

難道你不能簡單地讓你的集成測試項目瞭解它們嗎(通過引用或以某種方式啓動它們)?這兩個服務不需要彼此瞭解,但是我認爲在引用它們的測試項目中沒有任何傷害。 – kkirk

+0

在此閱讀我的答案:https://stackoverflow.com/a/45177810/569662。 OP有關於如何管理服務依賴關係的類似問題。 –

+0

@kkirk但是,當您在處理客戶端項目時,您需要運行常規測試。因此,您需要將集成測試項目包含在客戶端解決方案中,否?如果我們可以引用依賴關係的DLL *,那就好了......但是我們如何保持最新的,即最新的和構建的? – Timo

回答

0

爲避免突破集成,請使用公共合同。例如,RAML。描述特定服務的客戶將獲得並通過的模型,描述操作和參數。在這種情況下,沒有人依賴於特定的服務或實施,雙方都需要測試他們與合同的溝通。

額外的安全措施將發佈您的合同作爲DLL。在這種情況下,服務的消費者會在一分鐘內注意到變化。如果他們有單元測試,他們可能會更早地顯示任何問題。

作爲一個保持分離的主要規則:不要參考實現,而是引用契約。

1

我希望我能理解你所問的內容,但如果不是這樣,以下內容至少對你的思維有所貢獻。

我理解你的問題的方式是一個非常實用的方法,即「如何組織解決方案和項目,以最大限度地降低開發人員違反服務合同而不理解其對服務消費者的影響的風險?」

在理想的世界中,開發人員不這樣做。如果他們對服務進行了重大更改,他們知道他們已經完成了,而且這是一個新版本。這就是說,我明白你的觀點 - 很高興能有一些抵禦這種人爲錯誤的保護措施,因爲開發人員大多數時間都是完美的。

如果您正在一個環境中工作,您正在創建其他團隊依賴的微服務,反之亦然,那麼就沒有辦法遵循嚴謹和結構化的方法,即適當的治理。一個能夠反映生產的完整測試環境,所有服務都在運行,並且您可以測試您的服務與其所依賴的服務的集成情況,但這並不會造成任何影響。

如果你在控制所有需要彼此通信的服務,那麼(至少在我看來)沒有理由不應該有一個解決方案,即你所有的服務項目都包含在哪裏以及哪裏您的集成測試項目將啓動所需的所有服務,並檢查它們之間的集成是否按預期工作。

除了契約/接口之外,您的個人微服務不應該知道外界的任何信息,您應該有單元測試來獨立地測試每個微服務,嘲笑依賴關係。

如果一個解決方案變得太大,您可以將其分解爲更小的部分,以便爲每個包含該服務及其最近鄰居的服務提供一個解決方案。在你的例子中,這可能是一個包含ThreeDSecureService,CreditCardService和CreditCardService.IntegrationTests(它測試CreditCardService,然後調用ThreeDSecureService)的解決方案。 這樣,當開發人員開發ThreeDSecureService時,集成測試將讓開發人員知道他/她已經破壞了集成。 這仍然需要開發人員記住當然實際運行Integration測試。

我認爲它的最終目標是在構建流程中加入一個門,以確保開發人員無法發佈會導致集成測試失敗並與自動部署相結合的更改。這將確保基本的整合錯誤不會使其投入生產。

+0

我喜歡讀這本書。 :)你會如何建議微服務「知道」合同?目前,他們有自己的序列化模型,*假設*他們所調用的服務仍然遵守該合同。 **我的目標是,如果這些合同改變了**(通常意味着有人搞砸了),就會提前發出警告。合同應該易於維護,並且在解決方案管理方面增加很少的開銷。 – Timo

+0

太棒了,我很高興這很有用。我建議在NuGet軟件包或類似軟件中定義合同的接口,這些接口是版本化的,以便您確切知道每個服務實現的合約。我通過爲每個服務定義一個單獨的命名空間來處理服務的版本控制,例如CreditCardService.v1_0,CreditCardService.v1_1等。 您可以對獨立的NuGet包中的數據模型執行相同的操作,NuGet包依賴於該包。 這樣,當所有服務都在相同版本的包上時,它們對每個數據模型都有完全相同的理解。 – kkirk

+0

有趣的想法。我也在考慮類似的選擇,比如只用契約來引用DLL,或者有一個大的Contracts項目(塞滿界面)被所有東西引用。我將不得不調查每個的利弊。 – Timo