Skip to main content
Last updated: 5 Dec 2022

Pact Testing

Pact is a tool we use for contract testing. Contract testing involves creating a set of tests that are shared between an API (the “provider”) and its users (“consumers”) using some kind of “broker”. For example, the Publishing API has a “pact” or “contract” with GDS API Adapters:

GDS API Adapters is really a proxy for real “consumer” apps, like Whitehall. The gem includes a set of shared stubs for use in each app’s own tests (example). Using the stubs ensures each app stays in sync with GDS API Adapters, which can then do contract testing on their behalf.

Running Pact tests locally

For a consumer (GDS API Adapters)

Pact tests are run as part of the regular test suite:

bundle exec rake test

Or they can be run on their own:

bundle exec rake pact_test

For a provider

Example for Frontend (provider of /bank-holidays.json):

bundle exec rake pact:verify

You can also test against a specific branch of GDS API Adapters:

env PACT_CONSUMER_VERSION=branch-<branch-of-gds-api-adapters> bundle exec rake pact:verify

Note: when a build runs for GDS API Adapters, the generated JSON pact is pushed to the broker as branch-<branch-name> using the pact:publish:branch rake task; this is why PACT_CONSUMER_VERSION needs to start with branch-.

Alternatively, you can test against local changes to GDS API Adapters:

env PACT_URI="../gds-api-adapters/spec/pacts/gds_api_adapters-bank_holidays_api.json" bundle exec rake pact:verify

Adding tests for a new app

If the app already had some Pact tests, follow the steps for changing existing Pact tests.

  1. Write the consumer and provider tests.

  2. Check the tests pass locally for both provider and consumer

    • CI won’t be able to test them yet as they won’t be pushed to the pact broker.
  3. Merge the consumer tests for the new app.

  4. Merge a GitHub Action (example) into the provider app to verify the pact

    • This will verify the provider app fulfills the contract published by the consumer.
  5. Update the consumer to utilise the provider GitHub action as part of the build process (example)

    • This will verify the provider contract when the consumer builds.

Changing existing Pact tests

Follow these steps in order to change the provider and consumer in tandem.

  1. Make the change to the API (your provider, e.g. Imminence), in a branch.

    • Its build should fail at the Pact test stage, because it is testing against the default branch of the consumer.
  2. Make the change to the pactfile in the consumer (e.g. GDS API Adapters), in a branch.

    • Its build should fail at the Pact test stage, because it is testing against the default branch of the provider.
  3. Confirm locally that the provider can verify against the published consumer pact

    • env PACT_CONSUMER_VERSION=branch-<branch-of-gds-api-adapters> bundle exec rake pact:verify
  4. Merge the provider change

    • We’ve configured failing Pact tests to not block merging, so you should still be able to merge.
  5. Re-run the consumer tests

    • These should pass now that the provider has been updated.
  6. Merge the consumer change

Special cases

Publishing API and Content Store have a direct pact, with Publishing API acting as the consumer and Content Store acting as the provider. This can be confusing as Publishing API is also a provider for GDS API Adapters.

The tests are run in the same way as other consumers and providers (see above).