X

A blog about Oracle Technology Network Japan

  • August 26, 2020

PactでJavaマイクロサービスをテストする

Guest Author

※本記事は、Alex Soto BuenoとAndy GumbrechtとJason Porterによる"How to Test Java Microservices with Pact"を翻訳したものです。


マイクロサービス・アプリケーションがもたらす独自のテスト課題

著者:Alex Soto Bueno、Andy Gumbrecht、Jason Porter

2020年4月6日

[編集注:本記事は、Alex Soto Bueno氏、Andy Gumbrecht氏、Jason Porter氏による書籍『Testing Java Microservices』(Manning、2018年)の「Contract Tests」の章に基づいています。]

 

マイクロサービス・アーキテクチャでは、マイクロサービス間で大量の通信が発生します。この相互通信により、サービス間のコントラクト(契約)が効果的に形成されます。このコントラクトは、入力データおよび出力データの期待値、そして事前条件と事後条件で構成されます。

あるサービスが要件を定め、その要件に基づいて別のサービスで提供(または生成)されるデータを使用する場合、そのようなサービスごとにコントラクトが形成されます。データを生成するサービスが時間によって変化する可能性がある場合、そのデータを使用する各サービスとのコントラクトが期待値を満たし続けることが重要です。コントラクト・テストでは、コンポーネントがコントラクトを満たすことを明示的に検証する仕組みが提供されます。

ここでは、コントラクト・テストを記述するために使用できるツールについて見ていきます。とりわけ、コンシューマ指向のコントラクト・テストをサポートするテスト・フレームワーク・ファミリーであるPactに注目します。Pactには、Ruby、JVM言語、.NET、JavaScript、Go、Python、Objective-C、PHP、Swiftの公式実装があります。

私たちの意見では、コントラクト・テストを行っている現場でもっとも普及し、成熟しているプロジェクトがPactフレームワークです。主な利点の1つとして、現在マイクロサービスを書くために使われている、ほぼすべての主要言語がサポートされていることが挙げられます。さらに、フロントエンドからバックエンドまで、プログラミング言語によらず同じ考え方を再利用できます。こういった理由から、Pactはコンシューマ指向コントラクトを記述するための、もっとも汎用的なソリューションであると強く確信しています。また、Javaで開発したマイクロサービス・アーキテクチャとの間には高い親和性があります。

 

Pactフレームワーク

Pactフレームワークにより、コンシューマ側でコントラクトを書くことができます。その際に、モックHTTPサーバーと柔軟なAPIを使い、コンシューマからサービス・プロバイダへのHTTPリクエストと、返されることが期待されるHTTPレスポンスを定義することができます。モックHTTPサーバーは、このHTTPのリクエストとレスポンスを使ってサービス・プロバイダを代行します。そして、その相互通信を使うことで、サービス・コンシューマとサービス・プロバイダの間のコントラクトが生成されます。

Pactではさらに、プロバイダ側と照合してコントラクトを検証するロジックも提供されます。コンシューマで発生した通信は、すべて「実際の」サービス・プロバイダに向けて再生されます。これによりプロバイダは、与えられたリクエストに対してコンシューマが期待するレスポンスを、確実に生成できるようになっています。予期しないものをプロバイダが返した場合、Pactは通信を失敗とマークし、コントラクト・テストは失敗します。

すべてのコントラクト・テストは、コンシューマのテストとプロバイダのテストという2つの部分で構成されます。加えて、コンシューマからプロバイダにコントラクト・ファイルが送信されます。Pactを使ったコントラクト・テストのライフサイクルは、以下のようになっています。

ステップ1:柔軟なAPIを使ってコンシューマの期待値をモックHTTPサーバーにセットアップします。コンシューマは、HTTPのリクエストとレスポンスを処理するモックHTTPサーバーと通信しますが、プロバイダとは通信しません。このようにすることで、コンシューマがプロバイダのデプロイ方法を知る必要はなくなります(この方法を知るのは簡単ではなく、コントラクト・テストではなくエンド・ツー・エンド・テストを書くことになる可能性が高いからです)。コンシューマは定義された相互通信を使い、クライアントやゲートウェイのコードがモックHTTPサーバーと通信できることを確認します。

コンシューマ・テストが実行されると、すべての相互通信がpactコントラクト・ファイルに書き込まれます。このファイルでは、コンシューマとプロバイダが従わなければならないコントラクトを定義します。

ステップ2:pactコントラクト・ファイルがプロバイダ・プロジェクトに送信され、プロバイダ・サービスに向けて再生されます。コントラクトが実際のプロバイダに向けて再生されると、プロバイダからの実際のレスポンスが、コントラクトで定義された、期待されるレスポンスと照合されます。

コンシューマがpactコントラクト・ファイルを生成でき、プロバイダがすべての期待値を満たす場合、両者によるコントラクトの検証が完了し、両者は通信できるようになります。

以上のステップを図1に示します。

The two steps of the Pact contract-test lifecycle

 

図1:Pactによるコントラクト・テストのライフサイクルにおける2つのステップ

 

まとめると、Pactでは以下の機能が提供されます。

  • プロバイダに依存する必要がなくなるように、モックHTTPサーバーが提供されます。
  • 期待値を自動再生するHTTPクライアントが提供されます。
  • 期待値が再生される前に、期待される状態がコンシューマ側からプロバイダに送信されます。たとえば、通信のためには、期待値が再生される前に、プロバイダのデータベースにAlexandraというユーザーが含まれていなければならないというような場合があります。
  • Pact Brokerは、コントラクトのリポジトリです。Pact Brokerにより、pactをコンシューマとプロバイダで共有できます。また、プロバイダが固定のバージョンのコントラクトと照合して自身を検証できるように、pactコントラクト・ファイルのバージョン管理が行われます。さらに、各pactのドキュメントが提供されるとともに、サービス間のリレーションシップが視覚化されます。

次は、Java仮想マシン向けのPact実装であるPact JVMについて見ていきます。

 

JVM言語でのPact

Pact JVMはScala、Groovy、Javaを使って書かれていますが、任意のJVM言語で使用できます。Java、Scala、Groovy、Grails(コントラクトを定義するためにGroovy DSLが提供されています)、Clojureとの間には、非常に高い親和性があります。さらに、JUnit、Spock、ScalaTest、Specs2などのテスト・フレームワークや、Maven、Gradle、Leiningen、sbtなどのビルド・ツールと緊密に統合されています。本記事ではJavaのツールについて取り上げますが、他のJVM言語を使う予定の方も、Pact JVMを用いてコンシューマ指向のコントラクト・テストを行えることは覚えておいてください。

次は、Pact JVMを使ってコンシューマ・テストとプロバイダ・テストを書く方法を紹介します。

Pact JVMによるコンシューマ・テスト:Pact JVMでは、モックHTTPサーバーと、モックHTTPサーバーの期待値を記述するJava DSLが提供されています。この期待値は、コンシューマ・テストに合格したときに、pactコントラクト・ファイルとして実体化されます。

Pact JVMはJUnitと統合されており、DSLと、JUnitでコンシューマ・テストをビルドする際に使用できるベース・クラスが提供されています。JUnitによるコンシューマ・テストを書くにあたって最初に行うことは、PactProviderRule JUnitルールの登録です。このルールでは、以下の処理を行います。

  • モックHTTPサーバーを起動、停止する
  • モックHTTPサーバーを定義済みの期待値で構成する
  • テストに合格した場合、定義済みの期待値からpactコントラクト・ファイルを生成する

次に例を示します。

@Rule public PactProviderRule mockProvider =
new PactProviderRule("test_provider", "localhost", 8080, this);

最初の引数は、現在のコンシューマ・コントラクトが定義するプロバイダの名前です。この名前は、指定されたコントラクトのプロバイダを参照するために使用します。続く2つは省略可能なパラメータで、モックHTTPサーバーがバインドされているホストとリスニングしているポートです。値が指定されていない場合、それぞれlocalhostと8080が使われます。最後のthisインスタンスは、自分がテストであることを示しています。

次に、メソッドにau.com.dius.pact.consumer.Pactアノテーションを付加して期待値を定義します。このメソッドは、PactDslWithProvider型のクラスを受け取り、PactFragmentを返さなければなりません。PactDslWithProviderはDSLパターンを使って構築されたJavaクラスで、モックHTTPサーバーが使われる場合に受け取ることが期待されるリクエストの説明を提供します。

名前からもわかるように、PactFragmentオブジェクトはコントラクトの断片です。このオブジェクトは、モックHTTPサーバーで期待値として使われることに加え、プロバイダの検証に使用するpactコントラクト・ファイルを生成するためにも使われます。断片は、完全なコントラクトでも、コントラクトの一部でも構いません。同じテスト・クラスに複数の断片が定義されている場合、すべての断片を合わせたものがpactコントラクト・ファイルになります。

@Pactメソッドには次のシグネチャが必要です。

@Pact(provider="test_provider", consumer="test_consumer")
public PactFragment createFragment(PactDslWithProvider builder) {
//...
}

@Pactアノテーションに、コントラクトに従う必要があるプロバイダの名前と、コントラクトを定義するコンシューマの名前を設定することに注目してください。この情報は、プロバイダからデータが提供されるすべてのコンシューマに対して確実にプロバイダ側のテストを実行するために重要です。

次のスニペットでは、リクエストとレスポンスの期待値を定義しています。PactDslWithProviderには、いくつかのオプションを定義できます。

return builder
   .uponReceiving("a request for something")
      .path("/hello")
      .method("POST")
      .body("{\"name\": \"Ada\"}")
   .willRespondWith() 
      .status(200)
      .body("{\"hello\": \"Ada\"}")
   .uponReceiving("another request for something") 
      .matchPath("/hello/[0-9]+") 
      .method("POST")
      .body("{\"name\": \"Ada\"}")
   .willRespondWith()
      .status(200) 
      .body("{\"hello\": \"Ada\"}") 
   .toFragment();

上記のサンプルでは、2つの期待値を定義しています。最初のリクエストは、コンシューマがPOSTメソッドを使って/helloにリクエストを送ったときに発生します。メッセージ本体には、JSONドキュメント{"name":"Ada"}が正確に含まれている必要があります。その場合、レスポンスはJSONドキュメント{"hello":"Ada"}となります。2つ目のリクエストは、パスが/helloで始まり、その後に有効な数値が続く場合に発生します。条件は最初のリクエストと同じです。

相互通信はいくつでも必要なだけ定義できることに注意してください。個々の通信はuponReceivingで始まり、その後にレスポンスを記録するためのwillRespondWithが続きます。

ところで、できるだけテストをシンプルにして可読性を保ち、「1つのメソッドで1つのタスク」のアプローチを維持するために、すべてを返す1つの大きな@Pactメソッドを定義するのではなく、すべての通信に対して複数の断片を使用することをお勧めします。

先ほどの定義における重要な側面の1つに、本体の内容がコントラクトで指定されているものと同じでなければならないという点があります。たとえば、最初のリクエストには、そのJSONドキュメントが{"name":"Ada"}である場合にのみレスポンスが提供されるという厳格な要件があります。名前がAda以外の場合、レスポンスは生成されません。レスポンス本体も同様です。JSONドキュメントが静的であるため、レスポンスは常に同じになります。

静的な値を設定できない場合、とりわけプロバイダに対してコントラクトを実行するときは、これが制限になる可能性があります。そのため、ビルダーのbodyメソッドは、JSON本体を動的に構築するために使用できるPactDslJsonBodyを受け取れるようになっています。

PactDslJsonBodyクラス:PactDslJsonBodyビルダー・クラスはDSLパターンを実装しています。このパターンを使用して、JSON本体を動的に構築することに加え、フィールドの正規表現や型の照合を定義することができます。いくつかの例を見てみます。

次のスニペットでは、配列を使わない単純なJSONドキュメントを生成しています。

DslPart body = new PactDslJsonBody()
   .stringType("name")
   .booleanType("happy")
   .id()
   .ipAddress("localAddress")
   .numberValue("age", 100);

xType形式を使って、省略可能な値パラメータを設定することもできます。このパラメータは、モックのレスポンスを返す際にサンプル値を生成するために使います。サンプルが指定されていない場合は、ランダムな値が生成されます。

先ほどのPactDslJsonBody定義は、次のような本体に一致します。

{
   "name" : "QWERTY", 
   "happy": false, 
   "id" : 1234, 
   "localAddress" : "127.0.0.1", 
   "age": 100,
}

必要な型の必要なフィールドがすべて含まれ、値が100であるageフィールドを持つドキュメントは、すべて有効である点に注意してください。

PactDslJsonBodyでは、配列の照合を定義するメソッドも提供されています。たとえば、リストが最小サイズまたは最大サイズの条件を満たすことの検証や、リスト内の各項目が指定されたサンプルと一致することの検証を行うことができます。

DslPart body = new PactDslJsonBody() 
   .minArrayLike("products", 1) 
      .id()
      .stringType("name")
      .stringMatcher("barcode", "a\\d+", "a1234")
      .closeObject()
   .closeArray();

上記の例の場合、products配列を空とすることはできません。そして、すべてのプロダクトにidとstring型のname、さらに「a」に数字のリストを加えた形式のbarcodeが存在する必要があります。

要素のサイズが重要でない場合は、次のようにすることもできます。

PactDslJsonArray.arrayEachLike()

   .date("expireDate", "mm/dd/yyyy", date) 
   .stringType("name") 
   .decimalType("amount", 100.0) 
   .closeObject()

上記の例では、各配列にexpireDate、name、amountという3つのフィールドが含まれる必要があります。さらに、モックのレスポンスの各要素について、expireDateフィールドに日付型の値が、nameフィールドにランダムな文字列が、amountに値100.0が含まれる必要があります。

おわかりのように、DslPartを使って本体を生成することにより、具体的なフィールドと値のペアではなく、フィールドの型を定義できます。これにより、プロバイダ側でコントラクトを検証する際のコントラクトの柔軟性が高まります。たとえば、プロバイダの検証フェーズで.body("{'name':'Ada'}")を設定する場合を考えてみます。プロバイダは、同じ値を持つJSONドキュメントを生成することになっています。これはほとんどの場合で正しいでしょうが、テスト用のデータセットが変わり、.body("{'name':'Ada'}")ではなく、.body("{'name':'Alexandra'}")を返すようになった場合、テストは失敗します。しかし、コントラクトという観点で見れば、いずれのレスポンスも有効です。

ここまでは、コンシューマ側でのPactによるコンシューマ指向コントラクトの書き方について見てきました。次は、プロバイダ部分でのテストの書き方を説明します。

Pact JVMによるプロバイダ・テスト:コンシューマ部分でテストを行い、pactコントラクト・ファイルを生成して公開した後は、実際のプロバイダに向けてコントラクトを再生する必要があります。この部分のテストはプロバイダ側で実行します。Pactでは、そのためのツールがいくつか提供されています。

  • JUnit:JUnitテストでコントラクトを検証するツール
  • Gradle、Leiningen、Maven、sbt:実行中のプロバイダと照合してコントラクトを検証するためのプラグイン
  • ScalaTest:実行中のプロバイダと照合してコントラクトを検証するための拡張機能
  • Specs2:実行中のプロバイダと照合してコントラクトを検証するための拡張機能

通常、上記の機能では、公開されたコントラクトを2つの方法で取得します。具体的には、Pact Brokerと使う方法と、実際の場所(ファイルまたはURL)を指定する方法です。取得メソッドをどのように構成するかは、コントラクトの再生方法によって変わります。たとえば、JUnitではアノテーションによるアプローチを使用しますが、Mavenではプラグインの構成セクションを使用します。

それでは、Maven、Gradle、JUnitを使用してプロバイダ検証を実装する方法を確認していきます。

Mavenを使ったコントラクト検証:Pactでは、プロバイダと照合してコントラクトを検証するMavenプラグインが提供されています。このプラグインを使うためには、pom.xmlのプラグイン・セクションに次の内容を追加します。

<plugin> 
   <groupId>au.com.dius</groupId> 
   <artifactId>pact-jvm-provider-maven_2.11</artifactId> 
   <version>3.5.0</version> 
</plugin>

次に、Mavenプラグインを構成し、検証するすべてのプロバイダを定義し、その確認に使用するコンシューマ・コントラクトの場所を定義する必要があります。

<plugin> 
   <groupId>au.com.dius</groupId> 
   <artifactId>pact-jvm-provider-maven_2.11</artifactId> 
   <version>3.2.10</version> 
   <configuration> 
      <serviceProviders> 
         <serviceProvider> 
            <name>provider1</name> 
            <protocol>http</protocol> 
            <host>localhost</host> 
            <port>8080</port> 
            <path>/</path> 
            <pactFileDirectory>path/to/pacts</pactFileDirectory> 
         </serviceProvider> 
      </serviceProviders> 
   </configuration> 
</plugin>

コントラクトを検証するためには、mvn pact:verifyを実行します。Mavenプラグインでは、指定されたディレクトリで定義されているすべてのpactコントラクトをロードし、指定されたプロバイダ名に一致するものを再生します。プロバイダと照合してすべてのコントラクトが検証されると、ビルドは成功します。そうでない場合、ビルドは失敗します。

Gradleを使ったコントラクト検証:Gradleプラグインでは、プロバイダと照合してコントラクトを検証する際に、Mavenと同様のアプローチを使用します。このプラグインを使うためには、build.gradleのpluginsセクションに次の内容を追加します。

plugins { 
   id "au.com.dius.pact" version "3.5.0" 
}

次に、Gradleプラグインを構成し、検証するプロバイダを定義し、その確認に使用するコンシューマ・コントラクトの場所を定義します。

pact {
   serviceProviders {
      provider1 {
         protocol = 'http' 
         host = 'localhost' 
         port = 8080 path = '/'
         hasPactsWith('manyConsumers') { 
            pactFileLocation = file('path/to/pacts') 
         }
      }
   }
}

コントラクトを検証するためには、gradlew pactVerifyを実行します。Gradleプラグインでは、指定されたディレクトリで定義されているすべてのPactコントラクトをロードし、指定されたプロバイダ名に一致するものを再生します。プロバイダと照合してすべてのコントラクトが検証されると、ビルドは成功します。そうでない場合、ビルドは失敗します。

最後に、ビルド・ツールには頼らず、JUnitを使ってプロバイダを検証する方法を説明します。

JUnitを使ったコントラクト検証:Pactでは、プロバイダと照合してコントラクトを検証するJUnitランナーが提供されています。このランナーには、構成されたプロバイダに向けてすべてのコントラクトを自動再生するHTTPクライアントが含まれています。さらに、アノテーションを使ってすぐにpactをロードできる便利な方法も提供されています。

JUnitによるアプローチを使う場合、PactRunnerを登録し、@Providerアノテーションにプロバイダ名を指定して、コントラクトの場所を設定する必要があります。その後、au.com.dius.pact.provider.junit.target.Target型のフィールドを作成して@TestTargetアノテーションを付加します。そして、au.com.dius.pact.provider.junit.target.HttpTargetのインスタンスを作成し、pactコントラクト・ファイルをHTTPリクエストとして再生してレスポンスをアサートします。または、au.com.dius.pact.provider.junit.target.AmqpTargetのインスタンスを作成し、pactコントラクト・ファイルをAdvanced Message Queuing Protocol(AMQP)メッセージとして再生することも可能です(AMQPはメッセージ指向ミドルウェア用のアプリケーション・レイヤー・プロトコルで、メッセージ・オリエンテーション、キューイング、ルーティング、信頼性、セキュリティの各機能が定義されています)。

PactTest.javaからHttpTargetを使う例を見てみます。

@RunWith(PactRunner.class) 
@Provider("provider1") 
@PactFolder("pacts") 
public class ContractTest {
   @TestTarget 
   public final Target target = new HttpTarget("localhost", 8332);
}

@Testアノテーションが付加されたテスト・メソッドがないことに注意してください。そういったテスト・メソッドが必要でないのは、テストは1つではなく、多数存在するからです。つまり、コンシューマとプロバイダの間の1回の通信につき、1つのテストが存在します。

このテストを実行すると、JUnitランナーではpactsディレクトリからすべてのコントラクト・ファイルを取得し、そこで定義されているすべての通信をプロバイダの場所に向けて再生します。プロバイダの場所は、HttpTargetインスタンスで指定されているものを使います。

PactRunnerでは、テスト・クラスのアノテーションに基づいて自動的にコントラクトをロードします。Pactでは、そのためのアノテーションが3つ提供されています。

  • PactFolder:プロジェクト・フォルダまたはリソース・フォルダからコントラクトを取得します。例:@PactFolder("subfolder/in/resource/directory")
  • PactUrl:URLからコントラクトを取得します。例:@PactUrl(urls = {"http://myserver/contract1.json"})
  • PactBroker:PactBrokerからコントラクトを取得します。例:@PactBroker (host="pactbroker", port = "80", tags = {"latest", "dev"})
  • Custom:カスタムの取得機能を実装するためには、PactLoaderインタフェースを実装し、1つの空のデフォルト・コンストラクタを持つか、またはClass型の1つの引数(テスト・クラスを表します)があるコンストラクタを持つクラスを作成します。そして、次のようにしてテストにアノテーションを付加します。@PactSource(CustomPactLoader.class)

独自のメソッドも容易に実装できます。

Pactの状態:テストを行う場合、それぞれの通信は別々に検証する必要があります。以前の通信のコンテキストは一切引き継ぐべきではありません。しかし、コンシューマ指向コントラクトでは、プロバイダがコンシューマの期待値に一致するレスポンスを送れるようにするため、通信を実行する前にコンシューマがプロバイダ側で何かを準備したい場合もあります。一般的な使用例として、期待されるデータが格納されたデータソースを準備する場合が挙げられます。たとえば、認証操作のコントラクトをテストする際、通信が発生したときにプロバイダのロジックが適切にデータに反応できるように、プロバイダがあらかじめ実際のログインやパスワードをデータベースに挿入しておくことがコンシューマにとって必要な場合があります。図2は、コンシューマ、状態、プロバイダ間の相互通信についてまとめたものです。

The interaction between the consumers, states, and provider

 

図2:コンシューマ、状態、プロバイダ間の相互通信

まず、次に示すJSON本体を含むPOSTメソッドで認証プロセスを実行する必要があることを、コンシューマ側で定義します。

{ "login": "John", "password": "1234" }

このスニペットはプロバイダに向けてコントラクトを再生する際に使われるため、コンシューマはプロバイダに向けて通信を行う前に、指定された情報を使ってデータベースの準備をするようプロバイダに警告する必要があります。そのために、コンシューマはState Authenticationと呼ばれる状態を作成します。この状態には、必要なデータがすべて含まれ、状態の情報はコントラクトの中に格納されます。

プロバイダに向けてコントラクトが再生されたときは、テストでコントラクト検証の環境を準備できるように、通信が行われる前に状態データがテストに注入されます。最後に、期待されるユーザー情報を含むデータベースを使用してコントラクトの検証が実行されます。

コンシューマ側から状態を定義するためには、コントラクトの定義の際に特別なメソッドgivenを使う必要があります。

@Override 
protected PactFragment createFragment(PactDslWithProvider builder) { 
   Map<String, Object> parameters = new HashMap<>();
   parameters.put("login", "John"); 
   parameters.put("password", "1234") 
   builder 
      .given("State Authentication", parameters) 
      .uponReceiving("")
      …..

プロバイダ側で状態に反応するためには、@Stateアノテーションを付加したメソッドを作成する必要があります。

@State("State Authentication") 
public void testStateMethod(Map<String, Object> params) { 
   //データの挿入 
}

状態を使うことで、コンシューマとプロバイダの間で情報を共有できるため、通信が行われる前にテストの状態を構成できる点に注意してください。Pactの状態は、コンシューマ側からプロバイダの状態を準備する際に推奨される機能です。

MavenおよびGradleに組み込む場合も、プロバイダ側の状態を設定する方法が提供されています。その場合は、各プロバイダに状態変化URLを指定することで、プロバイダの状態を変更します。このURLでは、それぞれの通信が行われる前に、POSTメソッドを使ってpactコントラクト・ファイルからproviderStateの記述内容を受け取ります。

 

まとめ

コンシューマ指向のコントラクト・テストにPactを使うことには、さまざまなメリットがあります。

  • コンシューマ指向コントラクトを使うことで、テストの実行が高速化されます。
  • HTTPスタブ・サーバーがあるため、信頼できるレスポンスを常に受け取ることができ、テストの信頼度が向上します。
  • テストがコンシューマとプロバイダに分割されるため、失敗の原因を特定しやすくなります。
  • コンシューマ指向コントラクトの組み込みは設計プロセスです。
  • 「コンシューマ指向コントラクト」は「ダイレクタ・コンシューマ指向コントラクト」ではありません。コントラクトはコンシューマ側で始まる協調作業の開始点ですが、両方での作業が必要です。
  • コントラクト・テストでは、コンシューマ側がプロバイダ側のパッケージング方法やデプロイ方法を知っている必要はありません。コンシューマ側が知っている必要があるのは、コンシューマ部分をデプロイする方法のみです。プロバイダでコントラクトの検証を行うとき、プロバイダは、自身のデプロイ方法と、自身の依存性をモックまたはスタブする方法を知っています。これは、テストを実行できるようにするために完全な環境を開始しなければならないエンド・ツー・エンド・テストとは大きく異なります。

コンシューマ指向コントラクトは、従うべき最善のアプローチとは限らないかもしれません。通常、コンシューマ指向コントラクトは最善のアプローチですが、状況によっては、プロバイダ指向コントラクトやコンシューマ・コントラクトを使った方がよいでしょう。


Alex Soto Bueno

Red Hatの開発者グループに所属するソフトウェア・エンジニア。Javaの世界とソフトウェア自動化に情熱を抱き、オープンソース・ソフトウェア・モデルを信奉する。NoSQLUnitプロジェクトの創設者であり、JSR 374(Java API for JSON processing)Expert Groupのメンバー。『Testing Java Microservices』(Manning)の共著者、Istio Refcardの共同作成者でもあるほか、複数のオープンソース・プロジェクトに貢献している。2017年にJava Championとなり、マイクロサービス向けの新しいテスト技法、21世紀の継続的デリバリ、Javaについて国際的に講演を行っている。Twitterのフォローは@alexsotobから。

 

Andy Gumbrecht

Apache TomEE PMCメンバー、開発者であり、Tomitribeのエバンジェリストを務めた経験を持つ。現在は、Phoenix-Contact(ドイツ)でソフトウェア・アーキテクトとして勤務しつつ、OpenEJB、TomEEなどのApacheプロジェクトや、Arquillianテスト・フレームワークへの積極的な貢献を続けている。2009年以来、Apache OpenEJBとTomEEを本番環境で使い続け、貢献を繰り返す。1982年にメモリ1 KのSinclair ZX81を手にして以来、コンパクトなコードにこだわりを持っている。Twitterのフォローは@AndyGeeDeから。

 

Jason Porter

Red Hat開発者プログラム・チーム、Arquillian、Quarkus、その他のRed Hat内開発者エクスペリエンス・プロジェクトに携わるソフトウェア・エンジニア。専門はWildfly、Quarkus、CDI、JSF、Java EE、solr、Gradleなど。PHP、Ruby、Groovy、SASSや、その他の各種Web言語(HTML、CSS、JS)の経験を持つ。現在は、Red Hatのシニア・ソフトウェア・エンジニアとして主にdevelopers.redhat.com Webサイトに携わっており、開発者エクスペリエンスとその全方位的な改善に大きな関心を持つ。Twitterのフォローは@lightguardjpから。

 
 

 

 

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.