こんにちは、ソリューション開発部の桑原です。

現在私は、分科会活動として「マイクロサービスアーキテクチャ」の調査・検討を進めています。

本日は検討テーマの一つであるConsumer Driven Contract Testについて書いていきたいと思います。

Consumer Driven Contractとは

コンシューマ駆動契約はアーキテクチャに対するテスト駆動開発のようなもの

アーキテクチャレベルまで進歩させたテスト駆動開発

https://www.infoq.com/jp/news/2017/05/spring-cloud-contract

モノリシックなアプリケーションをサービス単位に分割などして、RESTなどで呼び出しているコードのテストを行おうとした場合、テストの実施方法として

  • 呼び出す全てのサービスをMock化
  • 呼び出す全てのサービスをDeploy

といった方法が考えられますが、

サービスのMock化

  • 実際には意味のないMockの作成をしてしまう危険性
  • 呼び出し先のサービスが変更されている場合、それに気付けない。(本番でエラーが発生して気がつくなど)

サービスのDeploy

  • 環境(NWやDB)、デプロイなどの準備が大変(開発スピードの低下)
  • 実行に時間がかかる

といったデメリットがあります。

Consumer Driven Contract testing

上に挙がっているデメリットへの対応策として生まれてきたのがConsumer Driven Contractというテスト駆動の考え方のようです。

サービスの呼び出し元をConsumer、呼び出し先をProviderと呼び、以下の手順によってConsumerとProviderの確からしさを検証する手法とのことです。

  1. ConsumerがProviderに期待する、特定の要求に対する応答をContractとする。

  2. ProviderとConsumerはそのContractに合意する。

  3. ConsumerはContractを元にMock化してしてテストを実施、ProviderはContractを守っていることを示すテストを実施。

上記の方法によってConsumerはMockを使ったテストを行いつつ、Providerに変更が加わったような場合もテスト結果によってすぐにわかる。といった仕組みになっています。

Spring Cloud Contractを使ってみる

今回はConsumer Driven Contract フレームワークの一つ、Spring Cloud Contractを実際に使ってみたいと思います。

下図のようにclientがConsumerへアクセスすると、ConsumerがProviderへ商品リストを問い合わせて返却する。といったとてもシンプルなコードで試してみます。

シーケンス図

Spring Bootで起動しており、Consumer、Provider、Goodsは以下の通りです。

それでは、実際にテストコードを書いていきたいと思います。

まずはConsumerとProviderの間に生まれるContractを下のようなGroovy DSLに記述していきます。
置き場所はProvider側のプロジェクトの、特に指定がない限り/src/test/resources/contractsとなります。
ファイル名はgoodsContract.groovyとしました。

Provider

まず、Providerのテストコード生成のために、

を実行すると、以下のようなContractVerifierTest.classが出来上がります。

その後、

を実行してみると [INFO] BUILD SUCCESS が表示されました。
ProviderがContractを保証していることがわかります。

Consumer

次にConsumer側です。先ほど作成したContract、goodsContract.groovyを元にProviderをモック化します。

  1. mvn spring-cloud-contract:convert :WireMock形式に変換(goodsContract.jsonが生成されます。)
  2. mvn spring-cloud-contract:run :モックサーバの起動。

    とログ出力されます。
    (このときのポート番号は起動のたびに変わるみたいです。)

起動したモックサーバを使用するためには、Consumer側の/src/test/resources/配下に設定ファイルで、

を設定すればOKです。

あとはいつもどおりのテストコードを以下のように書いて

ConsumerもProvider同様、テストの成功を確認できました。

感想

最初にあげた、

  • 呼び出す全てのサービスをMock化
  • 呼び出す全てのサービスをDeploy

に対するデメリットがContractに注目したテストを行うことで見事に解消されている。と感じました。また、Providerに対するテストコードが自動化されていることがメンテナンスのしやすさに相当なメリットがあるように思えます。

今回触ったのはSpring Cloud Contractの中でもほんのごく一部ですので、また機会があれば更に掘り下げた記事を書きたく思っております。

参考(URL順)

 

この記事が気に入ったら
いいね!しよう

最新情報をお届けします

Twitter で「株式会社アークシステム」をフォローしよう!

Spring Cloud Contract を試してみたhttps://devlog.arksystems.co.jp/wp-content/uploads/2017/07/gf01a201308142000-1200x675.jpghttps://devlog.arksystems.co.jp/wp-content/uploads/2017/07/gf01a201308142000-150x150.jpgkuwabaraマイクロサービスアーキテクチャプログラミング分科会Java,Spring Boot,Microservices,Spring Cloud Contractこんにちは、ソリューション開発部の桑原です。 現在私は、分科会活動として「マイクロサービスアーキテクチャ」の調査・検討を進めています。 本日は検討テーマの一つであるConsumer Driven Contract Testについて書いていきたいと思います。 Consumer Driven Contractとはコンシューマ駆動契約はアーキテクチャに対するテスト駆動開発のようなもの アーキテクチャレベルまで進歩させたテスト駆動開発 https://www.infoq.com/jp/news/2017/05/spring-cloud-contractモノリシックなアプリケーションをサービス単位に分割などして、RESTなどで呼び出しているコードのテストを行おうとした場合、テストの実施方法として呼び出す全てのサービスをMock化 呼び出す全てのサービスをDeployといった方法が考えられますが、 サービスのMock化実際には意味のないMockの作成をしてしまう危険性 呼び出し先のサービスが変更されている場合、それに気付けない。(本番でエラーが発生して気がつくなど)サービスのDeploy環境(NWやDB)、デプロイなどの準備が大変(開発スピードの低下) 実行に時間がかかるといったデメリットがあります。 Consumer Driven Contract testing 上に挙がっているデメリットへの対応策として生まれてきたのがConsumer Driven Contractというテスト駆動の考え方のようです。 サービスの呼び出し元をConsumer、呼び出し先をProviderと呼び、以下の手順によってConsumerとProviderの確からしさを検証する手法とのことです。 ConsumerがProviderに期待する、特定の要求に対する応答をContractとする。 ProviderとConsumerはそのContractに合意する。 ConsumerはContractを元にMock化してしてテストを実施、ProviderはContractを守っていることを示すテストを実施。上記の方法によってConsumerはMockを使ったテストを行いつつ、Providerに変更が加わったような場合もテスト結果によってすぐにわかる。といった仕組みになっています。 Spring Cloud Contractを使ってみる 今回はConsumer Driven Contract フレームワークの一つ、Spring Cloud Contractを実際に使ってみたいと思います。 下図のようにclientがConsumerへアクセスすると、ConsumerがProviderへ商品リストを問い合わせて返却する。といったとてもシンプルなコードで試してみます。Spring Bootで起動しており、Consumer、Provider、Goodsは以下の通りです。それでは、実際にテストコードを書いていきたいと思います。 まずはConsumerとProviderの間に生まれるContractを下のようなGroovy DSLに記述していきます。 置き場所はProvider側のプロジェクトの、特に指定がない限り/src/test/resources/contractsとなります。 ファイル名はgoodsContract.groovyとしました。Provider まず、Providerのテストコード生成のために、を実行すると、以下のようなContractVerifierTest.classが出来上がります。その後、を実行してみると BUILD SUCCESS が表示されました。 ProviderがContractを保証していることがわかります。 Consumer 次にConsumer側です。先ほど作成したContract、goodsContract.groovyを元にProviderをモック化します。mvn spring-cloud-contract:convert :WireMock形式に変換(goodsContract.jsonが生成されます。) mvn spring-cloud-contract:run :モックサーバの起動。とログ出力されます。 (このときのポート番号は起動のたびに変わるみたいです。)起動したモックサーバを使用するためには、Consumer側の/src/test/resources/配下に設定ファイルで、を設定すればOKです。 あとはいつもどおりのテストコードを以下のように書いてConsumerもProvider同様、テストの成功を確認できました。 感想 最初にあげた、呼び出す全てのサービスをMock化 呼び出す全てのサービスをDeployに対するデメリットがContractに注目したテストを行うことで見事に解消されている。と感じました。また、Providerに対するテストコードが自動化されていることがメンテナンスのしやすさに相当なメリットがあるように思えます。 今回触ったのはSpring Cloud Contractの中でもほんのごく一部ですので、また機会があれば更に掘り下げた記事を書きたく思っております。 参考(URL順)Spring Cloud Contract Spring Cloud Contract Maven Plugin Application Pattern: Consumer Driven Contracts サービス分割時の複雑性に対処する: テスト戦略の話 Consumer-Driven Contracts testingを徹底解説! Spring Cloud ContractについてMarcin Grzejszczak氏とのQ&A Consumer Driven...ARK Solution Development Division Developers Blog.