Lastminute.comは、システムレベルの統合テストを使用することで生じる困難を軽減し、フィードバックサイクルと開発プロセスを改善するためにコントラクトテスト(Contract Test)採用し、eBayは、内部APIを安全に進化させ、クライアントチームの要件をサポートするためにコントラクトテストを採用している。
マイクロサービスアーキテクチャのような分散システムでは、アプリケーションサービスはRPCスタイルのリクエストや非同期メッセージを使ってやり取りする。このようなシステムをテストする一般的なアプローチは、システムテスト(エンドツーエンドの統合テスト)で、通常、システム全体をテスト環境に展開することが必要だ。
lastminute.comのソフトウェアエンジニアであるIvan Dell'oro氏は、統合テストやシステムテストを使用する際の課題を強調した。
2つのマイクロサービス間のメッセージ交換を検証するために統合テストを実施したところ、複数の理由で失敗しました。この弱点から、開発プロセスを阻害しないように、これらのテストを無視するようになりました。その結果、何ヶ月も無視されたままになってしまい、相手側で何かが変わったとき、CIパイプラインの両方が緑色になりました。通常、本番環境で何かが失敗したときに、コントラクトに誤りがあることに気づきます。
eBayのNotification Platformチームにとってのもう1つの課題は、私たちのAPIが多くのドメインチームによって利用されることです。サービスAPIを進化させながら、すべてのコンシューマーとの互換性を維持することは、私たちにとって基本的な原則です。
とeBayチームは発言している。
両チームとも、テストを 堅牢で速くする方法を探してきた。その目的は、API仕様やメッセージスキーマといった内部接点の進化をサポートしながら、開発者/テスターの体験を改善し、フィードバックサイクルを短縮して価値提供のペースを高めることだった。
最終的には、いくつかの調査と実験の後、サービス間インタラクションの正しさを検証する主な方法として、コントラクトテストを採用した。その結果、lastminute.comは、標準的なシステムレベルのテストと比較して、テスト実行時間が大幅に短縮され、マイクロサービス・アーキテクチャと配信プロセスにプラスの影響を与えることを確認した。 eBayは、コントラクトテストを使用して、プラットフォームの統合ポイントを検証し、非互換性の問題なしに内部APIが進化できるようにする共同作業を支援している。
Lastminute.comは、Consumer-Driven Contracts TestツールであるPactを使用して、マイクロサービス間のRPCインタラクションにコントラクトテストをすでに採用しており、その後、サービスがRabbitMQブローカーを介してメッセージを交換する非同期インタラクションに使用を拡大した。
出典: https://technology.lastminute.com/contract-testing-asynchronous-messaging-pact-junit-mockk/
eBayのチームは、OpenAPI仕様に基づき、API定義のセマンティックバージョンアップを検討したが、バージョンアップだけでは脆弱なシステムテストの問題を解決するには不十分であると結論付けた。彼らは、APIコンシューマの要求を記述する方法としてBDD(振る舞い駆動開発)に注目し、プロデューサーとコンシューマのチームが協力してすべての要求を成文化し、実行可能なものにすることにした。しかし、このようなアプローチは、APIプロバイダーが顧客の要件を把握し、変更に応じて更新することに過度に依存することが判明し、問題があることが判明した。
チームは最終的にコントラクトテスティングを試してみることにした。このテストでは、テストケースにモック(またはスタブ)を使用することで、プロデューサとコンシューマのチームが独立したテストスイートを維持することができるのである。
Spring Cloud ContractとPactを評価し、よりストレートな使用パターンとチーム間の相互作用のサポートが優れていることから、後者に決定した。Pactflow(Pactの商用製品)と社内のCI/CDツールとのシームレスな統合を実現し、新しいコントラクトテストを構成するための専用の開発者ポータルを作成した。
出典: https://tech.ebayinc.com/engineering/api-evolution-with-confidence-a-case-study-of-contract-testing-adoption-at-ebay/
Dell'oro氏は、コントラクトテストだけでは、システムレベルの統合テストの完全な代替にはならないと強調した。コントラクトテストは、サービス間の正しいデータのやりとりを検証するためのものだが、サービスレベルの統合テストでは、全体的なプロセス/データの流れが正しく、弾力的であることを確認するために、ビジネスロジックとエラー処理の両方を実行しなければならないからだ。