Note
A helpful tip when analyzing test results is to specify the value of logLevel
in your Pact options.
Let's talk a little about some common issues and questions when implementing contract tests.
Testing Pass-Through APIs
Pact may not be the best tool for testing pass-through APIs. During Pact verification, Pact does not test the side effects of a request being executed on a provider. It simply checks that the response body matches the expected response body. If your API passes a message (such as a key) to a downstream system without validating the contents of the body, you could technically send anything in the request body and the provider would respond in exactly the same way.
The contract we are interested in is between the consumer and the downstream system. Checking that the provider responded with a return code of 200 doesn’t necessarily indicate with high confidence that your consumer in the downstream system will work correctly in a real world scenario. What you really need is a non-HTTP Pact between your consumer and the downstream system. Here’s an example of how to use Pact contract generation as well as matching code to test non-HTTP communications.
Testing Public APIs
Pact may not be the tool for you if you are testing public APIs. How do you test a request that requires data to already exist on the provider? Provider estates allow you to set up data on the provider by injecting it directly into the data source before the interaction is run. Subsequently a response can be made that matches what the consumer expects. They also allow the consumer to make the same request with different expected responses. If you use Pact to test a public API, the only way to set up the right provider estate is to use the very API that you are actually testing. This has the consequence of making tests slower and more brittle compared to normal Pact verification tests.
Implementing Contract Tests in a Live Project
Trying to implement Pact with an ongoing project can be difficult. If your services are already up and running, you may find Pact integration to be problematic as several workarounds may be necessary to implement contract testing.
Achieving Pact Nirvana
Pact has a huge community with extensive support. It has created guidance documentation explaining how to achieve so-called “Pact Nirvana.” It essentially covers most of the best practices discussed in Chapter 5 but is included here for completeness:
Let's quickly review these points again and do a deeper dive into ones not yet discussed.
Talk
If there are problems with communication you might make things worse, eventually forcing your hand in making improvements.
Spike
Create a spike. First try and review the challenges you are facing.
Write and Verify a Pact for a Real Consumer and Provider
This task could take place as part of our spike investigation.
Automate the Contract and Verification Results Exchange
Edit the contract test to fit your pipeline.
Create Workflow to Accommodate Workflow Changes
Create a Workflow that allows contracts to change without breaking your builds. Get the latest published contract from the Pacts broker.
Use Tags for Compatibility
Use tags to ensure that your provider is compatible with your production consumer.
Use The Pact “Matrix” as a Gateway to Deployments
Use the Pact matrix as a gateway to deployments. Pact manages the compatibility between different versions of services with a matrix created from a table of all the consumer and provider versions that have been tested against each other using Pact. You can view the Pact matrix for any pair of applications in your Pact broker.
The Final Step
The final step to achieving Pact nirvana is to have a CI build that checks out the code for the production version of your provider.