Microservices are becoming increasingly popular in the landscape of Service-Oriented Architecture, and one strategy to test Microservices is Contract Testing. So in this blog, we will learn about Consumer-Driven Contract Testing.
- Microservices provide a degree of granularity and flexibility that allows projects to scale the service with ease.
- When a project is built with a lower number of microservices, it is easy to communicate with the provider about the changes to the specific microservice.
- Whereas once the project is using a large number of microservices (have a look at Amazon and Netflix’s services), this becomes more complicated for example if one of the services changes the structure of the output response or the structure of the request body.
- Here is where Contract Testing comes into the picture. Contract testing fits very well at the service layer. And they execute quickly and don’t need to integrate to external systems to run.
- Their job is to give you confidence that the systems you integrate with are compatible with your code before you release it.
Contract test over end to end integration tests
- E2E tests are not that quick since they talk to multiple systems.
- Verify that the system as a whole meets the business needs.
- They run fast because they don’t need to talk to multiple systems.
- They are easier to maintain, you don’t need to understand the entire ecosystem to write your tests.
What is Contract Testing?
- Contract testing is writing tests to make sure the services can communicate well with each other.
- There are two perspectives on Contract testing:
- One is the consumer entity using the service.
- The other is the provider entity that provides the service. As an example, these two parties can be a Frontend and Backend, or two Backend services integrating with each other.
- In our example used in the next chapters, we can say that the set of assertions generated by all consumers, expresses the mandatory structure of the messages to be exchanged during the period in which the assertions remain valid for their parent applications.
- If the provider were possessed of this set of assertions, it would be able to ensure that every message it sends is valid for every consumer insofar as the set of assertions is valid and complete.
- contract tests provide confidence for consumers of external services, they are even more valuable to the maintainers of those services.
- Consider the provider exposes three attributes: Id, name, and age, and this service consume by three different consumers.
- A only requires id and name attribute and not age. And then in such case the contract tests only assert these two attributes and ignore the age attribute.
- Consumer B only requires the id and age attribute and not the name. And then in such case, the contract tests only assert these two attributes and ignore the name attribute.
- Consumer C requires all three fields and has a contract test suite that asserts they are all present.
- If a new consumer adopts the API but requires both firstName and lastName, the provider removes the name and introduces another field as first and last name.
- Now when the provider runs the contract tests, the test would fail as Consumer A and Consumer C require a name field. In this case, the provider marks the name as deprecated and after Consumer A and C are migrated to the new field, the deprecated field is removed.