Skip to main content

Provider Testing

Pact is a consumer-driven contract testing tool. This means that the consumer specifies the expected interactions with the provider, and these interactions are used to create a contract. This contract is then used to verify that the provider behaves as expected.

The provider verification process works by replaying the interactions from the consumer against the provider and checking that the responses match what was expected. This is done by using the Pact files created by the consumer tests, either by reading them from a local filesystem, or by fetching them from a Pact Broker.

Verifying Pacts​

Command Line Interface​

Pact Python comes bundled1 with the pact-verifier CLI tool to verify your provider. It is located at within the {site-packages}/pact/bin directory, and the following command will add it to your path:

=== "Linux / macOS (sh)"

```bash
site_packages=$(python -c 'import sysconfig; print(sysconfig.get_path("purelib"))')
if [ -d "$sit_p_packages/pact/bi ]; then]; then
export PATH_p$site_packages/pact/bin:$P
else
echo "Pact CLI not found."
fi
```

=== "Windows (pwsh)"

```pwsh
$sitePackages = (python -c 'import sysconfig; print(sysconfig.get_path("purelib"))')
if (Test-Path "$sitePackages/pact/bin") {
$env:PATH += ";$sitePackages/pact/bin"
} else {
Write-Host "Pact CLI not found."
}
```

You can verify that the CLI is available by running:

pact-verifier --help

A minimal invocation of the Pact verifier looks like this:

pact-verifier ./pacts/ \
--provider-base-url=http://localhost:8080

This will verify all the Pacts in the ./pacts/ directory against the provider located at http://localhost:8080.

Options​

OptionDescription
--provider-base-url TEXTBase URL of the provider to verify against. [required]
--provider-states-setup-url TEXTURL to send POST requests to setup a given provider state.
--pact-broker-username TEXTUsername for Pact Broker basic authentication. Can also be specified via the environment variable PACT_BROKER_USERNAME.
--pact-broker-url TEXTBase URl for the Pact Broker instance to publish pacts to. Can also be specified via the environment variable PACT_BROKER_BASE_URL.
--consumer-version-tag TEXTRetrieve the latest pacts with this consumer version tag. Used in conjunction with --provider. May be specified multiple times.
--consumer-version-selector TEXTRetrieve the latest pacts with this consumer version selector. Used in conjunction with --provider. May be specified multiple times.
--provider-version-tag TEXTTag to apply to the provider application version. May be specified multiple times.
--provider-version-branch TEXTThe name of the branch the provider version belongs to.
--pact-broker-password TEXTPassword for Pact Broker basic authentication. Can also be specified via the environment variable PACT_BROKER_PASSWORD.
--pact-broker-token TEXTBearer token for Pact Broker authentication. Can also be specified via the environment variable PACT_BROKER_TOKEN.
--provider TEXTRetrieve the latest pacts for this provider.
--custom-provider-header TEXTHeader to add to provider state set up and pact verification requests. eg 'Authorization: Basic cGFjdDpwYWN0'. May be specified multiple times.
-t, --timeout INTEGERThe duration in seconds we should wait to confirm that the verification process was successful. Defaults to 30.
-a, --provider-app-version TEXTThe provider application version. Required for publishing verification results.
-r, --publish-verification-resultsPublish verification results to the broker.
--verbose / --no-verboseToggle verbose logging, defaults to False.
--log-dir TEXTThe directory for the pact.log file.
--log-level TEXTThe logging level.
--enable-pending / --no-enable-pendingAllow pacts which are in pending state to be verified without causing the overall task to fail. For more information, see pact.io/pending
--include-wip-pacts-since TEXTAutomatically include the pending pacts in the verification step. For more information, see WIP pacts
--helpShow this message and exit.

??? note "Deprecated Options"

| Option                       | Description                                                                                                                                                                        |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--pact-url TEXT` | specify pacts as arguments instead. The URI of the pact to verify. Can be an HTTP URI, a local file or directory path. It can be specified multiple times to verify several pacts. |
| `--pact-urls TEXT` | specify pacts as arguments instead. The URI(s) of the pact to verify. Can be an HTTP URI(s) or local file path(s). Provide multiple URI separated by a comma. |
| `--provider-states-url TEXT` | URL to fetch the provider states for the given provider API. |

Python API​

Pact Python also provides a pythonic wrapper around the command line interface, allowing you to use the Pact verifier directly from your Python code. This can be useful if you want to integrate the verifier into your test suite or CI/CD pipeline.

To use the Python API, you need to import the Verifier class from the pact module:

verifier = Verifier(
provider='UserService',
provider_base_url="http://localhost:8080",
)

If you are verifying Pacts from the local filesystem, you can use the verify_pacts method:

success, logs = verifier.verify_pacts('./userserviceclient-userservice.json')
assert success == 0

On the other hand, if you are using a Pact Broker, you can use the verify_with_broker method:

success, logs = verifier.verify_with_broker(
broker_url=PACT_BROKER_URL,
# Auth options
)
assert success == 0

Where the auth options can either be broker_username and broker_password for OSS Pact Broker, or broker_token for PactFlow.

The CLI options are available as keyword arguments to the various methods of the Verifier class:

CLInative Python
--log-dirlog_dir
--log-levellog_level
--provider-app-versionprovider_app_version
--headerscustom_provider_headers
--consumer-version-tagconsumer_tags
--provider-version-tagprovider_tags
--provider-states-setup-urlprovider_states_setup_url
--verboseverbose
--consumer-version-selectorconsumer_selectors
--publish-verification-resultspublish_verification_results
--provider-version-branchprovider_version_branch

You can see more details in the examples

Provider States​

In general, the consumer will make a request to the provider under the assumption that the provider has certain data, or is in a certain state. This is expressed in the consumer side through the .given(...) method. For example, given("user 123 exists") assumes that the provider knows about a user with the ID 123.

To support this, the provider needs to be able to set up the state of the provider to match the expected state of the consumer. This is done through the --provider-states-setup-url option, which is a URL that the verifier will call to set up the provider state.

Managing the provider state is an important part of the provider testing process, and the best way to manage it will depend on your application. A couple of options include:

  1. Having an endpoint is part of the provider application, but not active in production. A call to this endpoint will set up the provider state, typically by [mocking][unittest.mock] the data store or external services. This method is used in the examples above.

  2. A separate application that has access to the same data store as the provider. This application can be started and stopped with different data store states.


  1. The CLI is available for most architecture, but if you are on a platform where the CLI is not bundled, you can install the Pact Ruby Standalone release.↩