Gradle プロジェクト
前提条件
プロジェクトで Spock を使用する場合は、spock-core モジュールと spock-spring モジュールを個別に追加する必要があります。詳細については、"Spock のドキュメント (英語) " を参照してください。 |
依存関係のある Gradle プラグインを追加する
依存関係のある Gradle プラグインを追加するには、次のようなコードを使用できます。
- プラグイン DSL GA バージョン
// build.gradle plugins { id "groovy" // this will work only for GA versions of Spring Cloud Contract id "org.springframework.cloud.contract" version "$\{GAVerifierVersion}" } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:$\{GAVerifierVersion}" } } dependencies { testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}" // example with adding Spock core and Spock Spring testImplementation "org.spockframework:spock-core:$\{spockVersion}" testImplementation "org.spockframework:spock-spring:$\{spockVersion}" testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier' }
- プラグイン DSL の非 GA バージョン
// settings.gradle pluginManagement { plugins { id "org.springframework.cloud.contract" version "$\{verifierVersion}" } repositories { // to pick from local .m2 mavenLocal() // for snapshots maven { url "https://repo.spring.io/snapshot" } // for milestones maven { url "https://repo.spring.io/milestone" } // for GA versions gradlePluginPortal() } } // build.gradle plugins { id "groovy" id "org.springframework.cloud.contract" } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:$\{verifierVersion}" } } dependencies { testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}" // example with adding Spock core and Spock Spring testImplementation "org.spockframework:spock-core:$\{spockVersion}" testImplementation "org.spockframework:spock-spring:$\{spockVersion}" testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier' }
- 従来のプラグインアプリケーション
// build.gradle buildscript { repositories { mavenCentral() } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:$\{springboot_version}" classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:$\{verifier_version}" // here you can also pass additional dependencies such as Kotlin spec e.g.: // classpath "org.springframework.cloud:spring-cloud-contract-spec-kotlin:$\{verifier_version}" } } apply plugin: 'groovy' apply plugin: 'org.springframework.cloud.contract' dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-contract-dependencies:$\{verifier_version}" } } dependencies { testImplementation "org.apache.groovy:groovy-all:$\{groovyVersion}" // example with adding Spock core and Spock Spring testImplementation "org.spockframework:spock-core:$\{spockVersion}" testImplementation "org.spockframework:spock-spring:$\{spockVersion}" testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-verifier' }
Gradle と安心の 2.0
デフォルトでは、Rest Assured 3.x がクラスパスに追加されます。ただし、Rest Assured 2.x を使用するには、次のように、代わりにそれを追加できます。
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:$\{springboot_version}"
classpath "org.springframework.cloud:spring-cloud-contract-gradle-plugin:$\{verifier_version}"
}
}
dependencies {
// all dependencies
// you can exclude rest-assured from spring-cloud-contract-verifier
testCompile "com.jayway.restassured:rest-assured:2.5.0"
testCompile "com.jayway.restassured:spring-mock-mvc:2.5.0"
}
こうすることで、プラグインは Rest Assured 2.x がクラスパス上に存在することを自動的に確認し、それに応じてインポートを変更します。
Gradle のスナップショットバージョン
追加のスナップショットリポジトリを settings.gradle
に追加すると、ビルドが成功するたびに自動的にアップロードされるスナップショットバージョンを使用できます。
スタブの追加
デフォルトでは、Spring Cloud Contract Verifier は src/contractTest/resources/contracts
ディレクトリでスタブを検索します。暫定的な目的で、プラグインは src/test/resources/contracts
の契約も検索しますが、このディレクトリは Spring Cloud Contract 3.0.0 の時点で非推奨です。
この新しい Gradle ソースセットでは、契約 テスト内で使用されるすべての基本クラスも src/contractTest/{language}
に移行する必要があることにも注意してください。{language}
は、目的に応じて Java または Groovy に置き換える必要があります。
スタブ定義を含むディレクトリはクラス名として扱われ、各スタブ定義は単一のテストとして扱われます。Spring Cloud Contract Verifier は、テストクラス名として使用されるディレクトリの少なくとも 1 レベルが含まれていることを前提としています。複数のレベルのネストされたディレクトリが存在する場合、最後のディレクトリを除くすべてがパッケージ名として使用されます。次の構造を考えてみましょう。
src/contractTest/resources/contracts/myservice/shouldCreateUser.groovy
src/contractTest/resources/contracts/myservice/shouldReturnUser.groovy
前述の構造を考慮すると、Spring Cloud Contract Verifier は 2 つのメソッドを使用して defaultBasePackage.MyService
という名前のテストクラスを作成します。
shouldCreateUser()
shouldReturnUser()
プラグインの実行
プラグインは、check
タスクの前に呼び出されるように自身を登録します。これをビルドプロセスの一部にしたい場合は、それ以上何もする必要はありません。テストを生成するだけの場合は、generateContractTests
タスクを呼び出します。
デフォルトのセットアップ
デフォルトの Gradle プラグインセットアップでは、ビルドの次の Gradle 部分が (擬似コードで) 作成されます。
contracts {
testFramework ='JUNIT'
testMode = 'MockMvc'
generatedTestJavaSourcesDir = project.file("$\{project.buildDir}/generated-test-sources/contractTest/java")
generatedTestGroovySourcesDir = project.file("$\{project.buildDir}/generated-test-sources/contractTest/groovy")
generatedTestResourcesDir = project.file("$\{project.buildDir}/generated-test-resources/contracts")
contractsDslDir = project.file("$\{project.projectDir}/src/contractTest/resources/contracts")
basePackageForTests = 'org.springframework.cloud.verifier.tests'
stubsOutputDir = project.file("$\{project.buildDir}/stubs")
sourceSet = null
}
def verifierStubsJar = tasks.register(type: Jar, name: 'verifierStubsJar', dependsOn: 'generateClientStubs') {
baseName = project.name
classifier = contracts.stubsSuffix
from contractVerifier.stubsOutputDir
}
def copyContracts = tasks.register(type: Copy, name: 'copyContracts') {
from contracts.contractsDslDir
into contracts.stubsOutputDir
}
verifierStubsJar.dependsOn copyContracts
プラグインの設定
デフォルト構成を変更するには、次のように、contracts
スニペットを Gradle 構成に追加します。
contracts {
testMode = 'MockMvc'
baseClassForTests = 'org.mycompany.tests'
generatedTestJavaSourcesDir = project.file('src/generatedContract')
}
リモートソースから契約をダウンロードするには、必要に応じて次のスニペットを使用できます。
contracts {
// If your contracts exist in a JAR archive published to a Maven repository
contractDependency {
stringNotation = ''
// OR
groupId = ''
artifactId = ''
version = ''
classifier = ''
}
// If your contracts exist in a Git SCM repository
contractRepository {
repositoryUrl = ''
// username = ''
// password = ''
}
// controls the nested location to find the contracts in either the JAR or Git SCM source
contractsPath = ''
}
Gradle の Jar パッケージ化タスクを使用しているため、verifierStubsJar
によって作成されたものをさらに拡張するために利用できるオプションと機能がいくつかあります。これを行うには、Gradle によって直接提供されるネイティブメカニズムを使用して、次のように既存のタスクをカスタマイズします。
例として、git.properties ファイルを verifierStubsJar に追加したいとします。 |
verifierStubsJar {
from("$\{buildDir}/resources/main/") {
include("git.properties")
}
}
3.0.0 以降、デフォルトのパブリケーションが無効になっていることにも注意してください。結果として、これは、Gradle 構成オプションを使用して通常行うのと同じように、任意の名前付き jar を作成し、公開できることを意味します。これは、希望どおりにカスタマイズした jar ファイルを構築し、それを公開して、jar のレイアウトとコンテンツを完全に制御できることを意味します。
構成オプション
testMode
: 受け入れテストのモードを定義します。デフォルトでは、モードは MockMvc で、Spring の MockMvc に基づいています。また、WebTestClient、JaxRsClient、Explicit (実際の HTTP 呼び出しの場合) に変更することもできます。imports
: 生成されたテストに含める必要があるインポートを含む配列を作成します (たとえば、['org.myorg.Matchers']
)。デフォルトでは、空の配列が作成されます。staticImports
: 生成されたテストに含める必要がある静的インポートを含む配列を作成します (たとえば、['org.myorg.Matchers.*']
)。デフォルトでは、空の配列が作成されます。basePackageForTests
: 生成されたすべてのテストの基本パッケージを指定します。設定されていない場合、値はbaseClassForTests
のパッケージおよびpackageWithBaseClasses
から選択されます。これらの値がどちらも設定されていない場合、値はorg.springframework.cloud.contract.verifier.tests
に設定されます。baseClassForTests
: 生成されたすべてのテストの基本クラスを作成します。デフォルトでは、Spock クラスを使用する場合、クラスはspock.lang.Specification
です。packageWithBaseClasses
: すべての基本クラスが存在するパッケージを定義します。この設定はbaseClassForTests
よりも優先されます。baseClassMappings
: 契約 パッケージを基本クラスの FQN に明示的にマップします。この設定はpackageWithBaseClasses
およびbaseClassForTests
よりも優先されます。ignoredFiles
:Antmatcher
を使用して、処理をスキップするスタブファイルを定義できるようにします。デフォルトでは、空の配列です。contractsDslDir
: GroovyDSL を使用して作成された契約を含むディレクトリを指定します。デフォルトでは、その値は$projectDir/src/contractTest/resources/contracts
です。generatedTestSourcesDir
: Groovy DSL から生成されたテストを配置するテストソースディレクトリを指定します。(非推奨)generatedTestJavaSourcesDir
: Groovy DSL から生成された Java/JUnit テストを配置するテストソースディレクトリを指定します。デフォルトでは、その値は$buildDir/generated-tes-sources/contractTest/java
です。generatedTestGroovySourcesDir
: Groovy DSL から生成された Groovy/Spock テストを配置するテストソースディレクトリを指定します。デフォルトでは、その値は$buildDir/generated-test-sources/contractTest/groovy
です。generatedTestResourcesDir
: Groovy DSL から生成されたテストで使用されるリソースを配置するテストリソースディレクトリを指定します。デフォルトでは、その値は$buildDir/generated-test-resources/contractTest
です。stubsOutputDir
: Groovy DSL から生成された WireMock スタブを配置するディレクトリを指定します。testFramework
: 使用するターゲットテストフレームワークを指定します。現在、Spock、JUnit 4 (TestFramework.JUNIT
)、および JUnit 5 がサポートされており、JUnit 4 がデフォルトのフレームワークです。contractsProperties
: Spring Cloud Contract コンポーネントに渡されるプロパティを含むマップ。これらのプロパティは、(たとえば) 組み込みまたはカスタムのスタブダウンローダーによって使用される可能性があります。sourceSet
: 契約が保存されるソースセット。指定しない場合は、contractTest
とみなされます (たとえば、JUnit の場合はproject.sourceSets.contractTest.java
、Spock の場合はproject.sourceSets.contractTest.groovy
)。
契約を含む JAR の場所を指定する場合は、次のプロパティを使用できます。
contractDependency
:groupid:artifactid:version:classifier
座標を提供する依存関係を指定します。contractDependency
クロージャーを使用してセットアップできます。contractsPath
: jar へのパスを指定します。契約の依存関係がダウンロードされる場合、パスはデフォルトでgroupid/artifactid
になり、groupid
はスラッシュで区切られます。それ以外の場合は、指定されたディレクトリにある契約をスキャンします。contractsMode
: 契約をダウンロードするモード (JAR がオフライン、リモートなどで利用可能かどうか) を指定します。deleteStubsAfterTest
:false
に設定すると、ダウンロードされた契約は一時ディレクトリから削除されません。failOnNoContracts
: 有効にすると、契約が見つからなかった場合に例外がスローされます。デフォルトはtrue
です。failOnInProgress
:true
に設定すると、進行中の契約が見つかると、ビルドが中断されます。プロデューサー側では、進行中の契約があるという事実を明確にし、コンシューマー側で偽陽性の検査結果が生じる可能性があることを考慮する必要があります。デフォルトはtrue
です。
次のプロパティを含む contractRepository { … }
クロージャもあります
repositoryUrl
: 契約定義が含まれるリポジトリへの URLusername
: リポジトリのユーザー名password
: リポジトリのパスワードproxyPort
: プロキシのポートproxyHost
: プロキシのホストcacheDownloadedContracts
:true
に設定すると、非スナップショット契約 アーティファクトがダウンロードされたフォルダーがキャッシュされます。デフォルトはtrue
です。
プラグインで次の実験的な機能を有効にすることもできます。
convertToYaml
: すべての DSL を宣言型 YAML 形式に変換します。これは、Groovy DSL で外部ライブラリを使用する場合に非常に役立ちます。この機能をオンにすると (true
に設定すると)、コンシューマー側でライブラリの依存関係を追加する必要がなくなります。assertJsonSize
: 生成されたテストで JSON 配列のサイズを確認できます。この機能はデフォルトでは無効になっています。
すべてのテストに対する単一の基本クラス
MockMvc (デフォルト) で Spring Cloud Contract Verifier を使用する場合、生成されるすべての受け入れテストの基本仕様を作成する必要があります。このクラスでは、検証する必要があるエンドポイントを指す必要があります。次の例は、その方法を示しています。
abstract class BaseMockMvcSpec extends Specification {
def setup() {
RestAssuredMockMvc.standaloneSetup(new PairIdController())
}
void isProperCorrelationId(Integer correlationId) {
assert correlationId == 123456
}
void isEmpty(String value) {
assert value == null
}
}
Explicit
モードを使用する場合は、通常の統合テストで見られるように、基本クラスを使用してテスト対象のアプリケーション全体を初期化できます。JAXRSCLIENT
モードを使用する場合、この基本クラスには protected WebTarget webTarget
フィールドも含まれている必要があります。現時点では、JAX-RS API をテストする唯一のオプションは、Web サーバーを起動することです。
契約のさまざまな基本クラス
基本クラスが契約間で異なる場合は、自動生成されたテストによってどのクラスを継承する必要があるかを Spring Cloud Contract プラグインに指示できます。次の 2 つのオプションがあります。
packageWithBaseClasses
を提供することで慣例に従いますbaseClassMappings
を使用して明示的なマッピングを提供する
慣例により
この規則では、(たとえば) src/contractTest/resources/contract/foo/bar/baz/
に契約があり、packageWithBaseClasses
プロパティの値を com.example.base
に設定した場合、Spring Cloud Contract Verifier は com.example.base
パッケージに BarBazBase
クラスがあると想定します。つまり、システムはパッケージの最後の 2 つの部分 (存在する場合) を取得し、Base
サフィックスを持つクラスを形成します。このルールは baseClassForTests
よりも優先されます。
マッピングによる
契約のパッケージの正規表現を、一致する契約の基本クラスの完全修飾名に手動でマップできます。contractPackageRegex
から baseClassFQN
へのマッピングを取る baseClassMapping
オブジェクトで構成される baseClassMappings
というリストを提供する必要があります。
次のディレクトリに契約があると仮定します。
src/contractTest/resources/contract/com/
src/contractTest/resources/contract/foo/
baseClassForTests
を提供することで、マッピングが成功しなかった場合のフォールバックが得られます。(フォールバックとして packageWithBaseClasses
を提供することもできます) こうすることで、src/contractTest/resources/contract/com/
契約から生成されたテストは com.example.ComBase
を継承し、残りのテストは com.example.FooBase
を継承します。
アーティファクトリポジトリへのスタブの公開
バイナリアーティファクトリポジトリを使用してスタブを保持する場合は、verifierStubsJar
を含めるように Gradle の公開セクションを構成する必要があります。これを行うには、以下の構成例を使用できます。
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
// other configuration
artifact verifierStubsJar
}
}
}
3.0.0 以降、内部スタブパブリケーションは非推奨になり、デフォルトで無効になっています。verifierStubsJar
を独自の出版物のいずれかに含めることをお勧めします。
スタブを SCM にプッシュする
SCM リポジトリを使用して契約とスタブを保持する場合は、スタブをリポジトリにプッシュする手順を自動化することができます。これを行うには、次のコマンドを実行して pushStubsToScm
タスクを呼び出します。
$ ./gradlew pushStubsToScm
SCM スタブダウンローダーの使用には、contractsProperties
フィールド (たとえば、contracts { contractsProperties = [foo:"bar"] }
)、contractsProperties
メソッド (たとえば、contracts { contractsProperties([foo:"bar"]) }
)、またはシステムプロパティまたは環境変数のいずれかを介して渡すことができるすべての構成オプションが表示されます。
コンシューマー側の Spring Cloud Contract 検証者
消費側サービスでは、プロバイダーの場合とまったく同じ方法で Spring Cloud Contract Verifier プラグインを構成する必要があります。スタブランナーを使用したくない場合は、次のコマンドを使用して、src/contractTest/resources/contracts
に保存されている契約をコピーし、WireMock JSON スタブを生成する必要があります。
./gradlew generateClientStubs
スタブ生成が機能するには、stubsOutputDir オプションを設定する必要があります。 |
JSON スタブが存在する場合、自動テストで JSON スタブを使用してサービスを利用できます。次の例は、その方法を示しています。
@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
class LoanApplicationServiceSpec extends Specification {
@ClassRule
@Shared
WireMockClassRule wireMockRule == new WireMockClassRule()
@Autowired
LoanApplicationService sut
def 'should successfully apply for loan'() {
given:
LoanApplication application =
new LoanApplication(client: new Client(clientPesel: '12345678901'), amount: 123.123)
when:
LoanApplicationResult loanApplication == sut.loanApplication(application)
then:
loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED
loanApplication.rejectionReason == null
}
}
前述の例では、LoanApplication
が FraudDetection
サービスを呼び出します。このリクエストは、Spring Cloud Contract Verifier によって生成されたスタブで構成された WireMock サーバーによって処理されます。