Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Using Contract Testing for Applications with Microservices

Using Contract Testing for Applications with Microservices

Leia em Português

This item in japanese

When using microservices, integration points between services are a hotbed for bugs. Consumer-driven contract testing is a technique where the consumer defines the contract and verifications are made against this contract within the providers build/test lifecycle. Contract testing fits well into a microservice workflow and it kills your integration bugs, argued Maarten Groeneweg, tester at Portbase, at the European Testing Conference 2019.

People are moving away from big monoliths to microservices because that helps them deliver at a faster pace, with less worrying about complexity. Microservices allow teams to release autonomously. End-2-end tests are defeating the purpose of having microservices, argued Groeneweg. Those tests are slow, high in complexity and teams are dependant on each other’s tests to move to production.

When you move into the direction of microservices, the number of integration points will explode. And each of those integration points has the risk of containing some bugs, said Groeneweg. Especially when services are made by different teams, the risk for small or bigger misunderstanding in (expected) behavior is high.

Groeneweg explained that contract testing consists of three steps:

  1. As a consumer of an API you write a "contract". This contract states what you expect from the provider (of an API). Based on this contract it generates a mock of the provider.
  2. As consumer you can test your own application against the mock of the provider.
  3. The contract can be sent over to the provider who can validate if the actual implementation matches the expectations in the contract.

What makes contract testing awesome is that it does this in a way which really fits well into a microservice workflow, said Groeneweg. The most important thing is that it decouples the test between the service who’s using the API (consumer) and the API itself (provider). This allows you to bring them both to production without needing the other. It’s especially useful when they are maintained by different teams because it enabled them to be autonomous in testing and releasing.

Groeneweg stated that contract testing is a way of reducing the risk of integration bugs. Also, contract testing is a lot faster than other ways of integration testing. That’s important as it allows you to decrease lead time and kill waste which is caused by slow feedback from tests, he said.

As the consumer defines the contract, contract testing also leads to better interfaces and APIs that are actually used.

InfoQ is covering the European Testing Conference 2019 and spoke with Maarten Groeneweg about contract testing.

InfoQ: What antipatterns exist in contract testing, and how can we deal with them?

Maarten Groeneweg: Contract Testing is a great type of testing to mitigate the integration risk between services. But, as with every type of testing, it sometimes can be difficult to implement. If you would like to start with Contract Testing I would like to warn you for seven anti-patterns.

  1. The nice thing about contract testing is that it allows the consumers of an API to write down their expectations. This can drive the development of the provider to make a solution which best fits the consumer’s wishes. But sometimes it moves from consumer-driven to consumer dictated.
  2. Tools can tempt to replace human interaction. This is also the case for contract testing. Doing feature request over contract testing or forcing teams to write contracts before having a good face-2-face discussion is a bad idea.
  3. When creating tests it’s important to have proper coverage. Don’t forget to test the not-so-happy flows. Scenarios as zero results or failed authentication are quickly overseen. But these are typical scenarios which might fail.
  4. As a consumer, you should only create a contract for what you need. Don’t use fields in contracts which you don’t need in your application. This way a provider has more freedom to change and optimize his services.
  5. To have contract tests between teams there is the need for some alignment. If one of the teams doesn’t agree on joining in, this can be difficult. By example, how can a provider know if their changes are not breaking any consumers if not all the consumers have their tests in place? So before you implement contract testing in your organization, make sure that teams are aligned.
  6. Sometimes people can complain that contract testing is complex. And they are right. But don’t let that stop you. All integration testing is complex; just look at your end-2-end tests… Also, a lot of complexity in testing can also be a smell of a very complex solution.
  7. As all automated tests, contract tests should be running in your delivery pipeline. You don’t want to rely on humans to run them, because at any point they will forget to do that. Setting up the pipeline for contract testing this can be a bit more complex than for other tests. The consumer and provider will have their own pipeline and those need to communicate to ensure that the tests are enforced in all cases. Forgetting to look at this will bite you. So it’s a good thing to read about this before you start.

InfoQ: You mentioned the antipattern of moving from consumer-driven to consumer dictated. How can this look?

Groeneweg: Let’s take the example where a consumer demands a specific combination of fields in the response. For the provider team, this specific combination is hard to implement as it will go across different databases and this makes it hard to implement, and if even possible the performance will be very poor. The consumer keeps pushing on this specific solution, without room for a healthy discussion. Now the contract is not driven by the consumer’s wish, but dictated by the consumer. In this situation the provider team will spend a lot of time and effort to end up with a solution which is very slow and everyone will be frustrated. The right approach, in this case, is to cooperate on the contracts and find the solution which works best for everyone.

InfoQ: If readers want to learn more about contract testing, where can they go?

Groeneweg: There are a lot of great resources on the internet about contract testing, including some good talks. I really like the documentation of PACT (a contract testing tool), it also includes some good articles about contract testing in general. Also, I listed some useful links on my website: contract testing.

Rate this Article