Skip to main content
Last updated: 17 May 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 alongside normal tests e.g.

bundle exec rake test 'TEST=test/imminence/*'

This will run both sets of tests for Imminence:

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 consumer tests pass locally.

    • CI won’t do this for you yet because it doesn’t know about the new app.
  3. Merge the consumer tests for the new app.

    • The build will pass because it runs with the old Jenkinsfile.
  4. Check the main build of the consumer.

  5. Merge tests for the provider.

    • Re-run the build if you made the PR before merging the consumer one.
  6. Re-run the main build for the consumer.

    • This will pass because the provider part now exists on the default branch.

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. Run a parameterised build of the consumer, specifying the new branch name of the provider to test against.

    • The build should pass so you can now merge the consumer PR, which will mean the change is on the default branch.
  4. Re-run the build for the provider PR now the consumer is merged.

    • The build should pass so you can now merge the provider PR.

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).