- Details can be found here spring cloud contract
- The same project is implemented using pact contract testing framework here. Refer to it for comparison
There are two flows
-
Producer defines the contract and then consumer creates tests that confirm to that contract
- Step 1: Producer creates a contract
- Step 2: Producer implement the controller and make the test pass
- Step 3: Producer publish the contract somewhere (in this case artifactory or some other maven repository)
- Step 4: Consumer import the contract
- Step 5: Consumer writes to test to ensure the consumer adheres to the contract
- Step 6: If consumer is not happy then the consumer can go back to producer and enhance the contract
-
A consumer defines the contract and producer implements the contract
- Step 1: Consumer check out
producer
repo - Step 2: Consumer add the desired contract in
producer
repo - Step 3: Consumer generate contract (the test will fail as not implemented here)
- Step 4: Consumer publish the contract (using mavenLocal most likely)
- Step 5: Consumer import the contract in
consumer
repo - Step 6: Consumer writes test to ensure that contract matches what it expects
- Step 7: Consumer creates a PR for
producer
repo - Step 8: Producer writes the necessary implementation to conform to the contract
- Step 9: Producer publishes the contract somewhere (in this case artifactory or some other maven repository)
- Step 10: Consumer consumes the now published contract and ensure that the test still passes
- Step 1: Consumer check out
Producer expose an endpoint /book
Follow the below steps to add/modify contract
- Navigate to folder
test/resources/contract
- Add a new folder for controller (one exists for
book
controller) - Use Groovy Contract Dsl to add new contract (see the
book
folder on how to create one) - Add a new base class if required to match the new contract (this would be required if you add a new controller or the existing controller needs some other test setup)
- Update
build.gradle
section below to add new baseClass mapping
contracts {
baseClassMappings {
baseClassMapping(".*book", "com.tabiul.producer.BookContractBase")
}
}
- Run the test
./gradlew :producer:test
.- If you do not want to run the test but just generate the contract then do
./gradlew :producer:generateContractTests
. This is useful if you want the contract be consumer driven rather than producer driven
- If you do not want to run the test but just generate the contract then do
- Publish the contract to local maven via
./gradlew :producer:publishToMavenLocal
- Add desired test case that interact with the producer
- Import the stub generated by the producer via
@AutoConfigureStubRunner(ids = ["contract-testing:producer:+:stubs:8081"], stubsMode = StubRunnerProperties.StubsMode.LOCAL)
stubsMode = StubRunnerProperties.StubsMode.LOCAL
becomesREMOTE
when the stubs are located in some external maven repository like artifactory
- Run test
./gradlew :consumer:test