In this article I will describe how to use testing frameworks as Spring Cloud and PACT in a consumer-driven TTD approach.
Consumer driven contract testing is a type of contract testing that ensures that a provider is compatible with the expectations that the consumer has of it.
For an HTTP API, this would involve checking that the provider accepts the expected requests, and that it returns the expected responses.
For a message queues system, this would involve checking that the provider generates the expected message.
With the consumer driven contract testing, the consumer drive the implementation of the provider and this makes TDD to be involved at the Architecture decision level.
Another benefit of contract testing is that microservices can be tested and released independently.
A consumer-driven contract workflow works as follows:
We have created 2 services projects, a provider and a consumer. Both services are not implemented yet.
Open the consumer’s project (Service 1) and create the consumer test:
a) No controller code is implemented yet.
Create test invoking the controller API.
Run test.
Test fails.
b) Write the controller.
The controller calls into Service 2 API (not written yet.)
Run test.
Test fails because of missing Service 2 controller.
3. Switch to the provider’s project (Service 2).
Add Spring contract verifier plugin.
Create the service contract’s definition for Service 2 in Groovy or Yaml.
Run maven install -DskipTest.
The Service 2-stub.jar file it is generated with the contract definitions and the request/response mappings created inside it.
Run verifier test for service 2.
Test fails because service 2 API’s functionality it is not implemented yet.
4. Switch back to the consumer’s project.
Add the stub library from 3).
Run consumer test.
Test passes even though the provider has not been implemented yet (because it matches the stub’s contract).
5. Switch to the provider’s project.
Generate contract verification code.
Run maven install noSkip.
Create the controllers and the internal logic for service 2 API.
Run the verifier test for service 2.
The verifier test passes for the provider.
Now, let's provide more details to this process.
The consumer-provider services interaction it is tested from two sides:
1) from the Consumer Side
Note: This step is for testing the contract, using the stub library generated based on the contract's definition. This step usually test the "happy" path, being interested to check if this contract will be maintained (or future changes to the service will break it).
2) from the Provider Side
On the provider side, this step it is called: contract verification.
Note: This step is for testing the real service's functionality, after the service has been fully implemented. This step test the negative test cases as well (i.e. a database the service relies on is not up and running).
The tasks that one needs to do are the following:
Download and execute the stub on the consumer side.
Generate and run contract verification tests on the provider side.
The consumer-driven contract workflow steps looks like below:
Note: In the article that will follow I will talk about:
DSL samples
Centralized repository for the contracts
References - Introduction to Spring Cloud Contract - by Andrew Morgan - on Pluralsight
Comments