Contract tests assert that inter-application messages conform to a shared understanding that is documented and verifiable. By testing against this shared understanding (a contract), it is possible to validate the compatibility of inter-connected systems before they are ever deployed to an integrated environment. This helps to enable more consistent stability of the integrated environments and helps to reduce the impact on other teams that are dependent on integrated environments, by enabling developers to detect breaking changes while working on their local machines and as an automated quality gate before deploying any changes.
Bi-Directional Contract Testing is a “Specification First Design” approach where the design API is constructed in the first place and then the actual implementation of the Provider takes place. It provides the same level of confidence that integrated system messages will be compatible between systems but allows for a more de-coupled workflow. Consumers still write unit tests and generate PACT files to serve as their documented expectations of provider service, however, Providers will instead validate their real service against all the versions of the published OAS spec of that service, and PactFlow will cross-check that both Consumer and Provider sides are compatible based on their results.
All Providers and Consumers should follow a consistent naming convention to ensure contracts are clear on which services/systems the interaction represents.
A Contract Test should cover connections to other systems/components where logic depends on any specific content in response to ensure the ability to identify breaking changes on the Consumer and Provider sides of any interaction.
Only connections where a consumer uses the response body should have Consumer Contract Tests written, and only for the fields used by the Consumer.
Provider services must be updated to match their OAS spec if they aren’t currently.
Create contract tests for the minimum data you expect from a given provider.
Always use an actual method from the service class to call the mock server in a test.
Use the same mocks for Unit, Component, and Contract tests.
Simply running PACT tests does not perform any compatibility validation. PactFlow does the cross-check once both the Consumer and provider upload their PACT files (and OAS spec).
Can-I-Deploy is the real gate-keeper of ensuring compatibility & stability and should be leveraged to realize the maximum benefits of Contract Testing.
Providers must ensure their real service and their OAS spec are in sync.
This is done through provider-side schema validation in the Bi-Directional Contract Testing approach.
Developers must run their contract tests locally before committing changes to catch issues as early as possible.
Best Practices for Writing Consumer Tests:
Note: This is only applicable to teams that use or build custom-developed APIs.
Practice | MVP | MVP+ |
---|---|---|
Train the team on Contract Testing |
+ |
|
Implement Contract Testing for one service |
+ |
|
Implement Contract Testing for all the services |
|
+ |
Tools:
Functionality | Tool Name |
---|---|
Contract Broker |
PactFlow |
CI/CD |
Azure pipelines |
Test code |
Programming language used by the team |
Roles:
Name | Responsibilities |
---|---|
|
Create Consumer contract tests against each external API that is used in their codebase Create Provider contract tests against each API that is developed within their codebase Ensure contract tests are configured and sent correctly into PactFlow Run contract tests locally after updating any code related to APIs / API interactions |
|
Create application, environment, team structure(s) in PactFlow to manage the roles/permissions/configurations in PactFlow for their system(s) |
|
Incorporate Contract Testing workflow into CI/CD pipelines to allow Contract Testing to serve as an automated quality gate |