Contract testing is the process of verifying that the API as it's defined in the API specification description (your OpenAPI file) aligns with the underlying API implementation (the running code). As you begin scaling out your API and service architecture, correctly documenting and validating the structure in which services communicate can ensure that API specifications meet the "reality" of the running service.
Benefits of contract testing include:
- Not Repeating Yourself: Don’t re-create test assertions that check for what is already described in your API specification.
- Governance: Quickly figure out if an API implementation conforms to the OpenAPI specification that was initially agreed upon.
- Single Source of Truth: Your API specification can become the single source of truth that describes your API. From it, you can generate documentation, SDKs, mock servers, and more. Incorporating the specification into your testing pipeline ensures that the specification accurately represents your API implementation over time.
This article describes how to leverage Stoplight's Prism API proxy server and Postman's request maker to run contract tests against your API.
Before starting, you'll need to have both Prism and Postman installed, as well as have a good understanding of how to use Postman. Be sure to visit the Postman Learning Center if you are new to Postman.
Starting a Proxy
Prism's proxy mode allows you to forward requests to a live, upstream API. When responses are proxied from Prism to the caller, the response data is validated against a linked API specification file for (contract) correctness.
To start Prism in proxy mode, use the "proxy" command and pass in an API specification/description and an URL to use for forwarding:
$ prism proxy petstore.yaml http://127.0.0.1:5000
[11:50:55 AM] › [CLI] … awaiting Starting Prism…
By default, Prism will listen on http://127.0.0.1:5000 for requests. See the Prism configuration options if you would like to customize this behavior.
Sending Requests from Postman
Once Prism is running, send requests from Postman to the Proxy URL (default http://127.0.0.1:5000) targeting a method and path that is defined in the linked API specification. This can involve sending one-off requests, or running a full collection if you already have tests defined.
Identifying Contract Violations
If at any point Prism detects a violation between what is defined in the contract (your API specification file) and what the API is responding with (the running code), a log is emitted to the Prism output and a "sl-violations" header is added to the response.
As an example, as part of our API response an array element has an invalid type:
Looking at the Prism output, an exception is logged:
And a sl-violations header is added to the response so that calling clients can be notified of the error:
Integrating Contract Tests into your Postman Collection
The final step here is to add an assertion to Postman to fail the test should a contract violation occur. This can be done with the test snippet:
pm.test("No contract violations are present", function () {
pm.response.to.not.have.header("sl-violations");
});
Which simply checks for the existence of the header.
Once added, requests will fail with an error citing a contract validation.
Now that contract validations are included in your tests, you can rest easy knowing that what's defined in your specification matches what has been implemented in code.