Skip to main content
https://img.shields.io/badge/license-MIT-brightgreen.svg https://img.shields.io/badge/python-2.7,%203.3,%203.4,%203.5,%203.6,%203.7,%203.8-brightgreen.svg https://img.shields.io/badge/pypi-0.1.1-brightgreen.svg https://img.shields.io/pypi/wheel/Django.svg https://travis-ci.org/Kalimaha/pact-test.svg?branch=master https://coveralls.io/repos/github/Kalimaha/pact-test/badge.svg?branch=development https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg

Pact Test for Python

This repository contains a Python implementation for Pact. Pact is a specification for Consumer Driven Contracts Testing. For further information about Pact project, contracts testing, pros and cons and useful resources please refer to the Pact website.

There are two phases in Consumer Driven Contracts Testing: a Consumer sets up a contract (it’s consumer driven after all!), and a Provider honours it. But, before that…

Installation

Pact Test is distributed through PyPi so it can be easily included in the requirements.txt file or normally installed with pip:

$ pip install pact-test

Providers Tests (Set the Contracts)

https://img.shields.io/badge/Pact-1.0-brightgreen.svg https://img.shields.io/badge/Pact-1.1-red.svg https://img.shields.io/badge/Pact-2.0-red.svg https://img.shields.io/badge/Pact-3.0-red.svg https://img.shields.io/badge/Pact-4.0-red.svg

Consumers run Provider Tests to create pacts and establish a contract between them and service providers. An example of a Python client using pact test is available at here. Consumers define all the interactions with their providers in the following way:

@service_consumer('PythonEats')
@has_pact_with('PyzzaHut')
class PyzzaHutTest(ServiceProviderTest):

    @given('some pizzas exist')
    @upon_receiving('a request for a pepperoni pizza')
    @with_request({'method': 'get', 'path': '/pizzas/pepperoni/'})
    @will_respond_with({'status': 200, 'body': {'id': 42, 'type': 'pepperoni'}})
    def test_get_pepperoni_pizza(self):
        pizza = get_pizza('pepperoni')
        assert pizza['id'] == 42
        assert pizza['type'] == 'pepperoni'

This test verifies, against a mock server, the expected interaction and creates a JSON file (the pact) that will be stored locally and also sent to the Pact Broker, if available. It is possible to define multiple tests for the same state in order to verify all the scenarios of interest, For example, we can test an unhappy 404 situation:

@given('some pizzas exist')
@upon_receiving('a request for an hawaiian pizza')
@with_request({'method': 'get', 'path': '/pizzas/hawaiian/'})
@will_respond_with({'status': 404, 'body': {'message': 'we do not serve pineapple with pizza'}})
def test_get_hawaiian_pizza(self):
    pizza = get_pizza('hawaiian')
    assert pizza.status_code == 404
    assert pizza.json()['message'] == 'we do not serve pineapple with pizza'

Consumers Tests (Honour Your Contracts)

https://img.shields.io/badge/Pact-1.0-brightgreen.svg https://img.shields.io/badge/Pact-1.1-red.svg https://img.shields.io/badge/Pact-2.0-red.svg https://img.shields.io/badge/Pact-3.0-red.svg https://img.shields.io/badge/Pact-4.0-red.svg

Providers run Consumer Tests to verify that they are honouring their pacts with the consumers. There are few examples of an hypothetical restaurant service implemented with the most popular Python web frameworks:

There are few things required to setup and run consumer tests.

Pact Helper

This helper class is used by Pact Test to start and stop the web-app before and after the test. It also defines the ports and endpoint to be used by the test. The following is an example of Pact Helper:

class RestaurantPactHelper(PactHelper):
    process = None

    def setup(self):
        self.process = subprocess.Popen('gunicorn start:app -w 3 -b :8080 --log-level error', shell=True)

    def tear_down(self):
        self.process.kill()

There are few rules for the helper:

  • it must extend PactHelper class from pact_test

  • it must define a setup method

  • it must define a tear_down method

It is also possible to override default url (localhost) and port (9999):

class RestaurantPactHelper(PactHelper):
    test_url = '0.0.0.0'
    test_port = 5000

States

When a consumer sets a pact, it defines certain states. States are basically pre-requisites to your test. Before honouring the pacts, a provider needs to define such states. For example:

@honours_pact_with('UberEats')
@pact_uri('http://Kalimaha.github.io/src/pacts/pact.json')
class UberEats(ServiceConsumerTest):

    @state('some menu items exist')
    def test_get_menu_items(self):
        DB.save(MenuItem('spam'))
        DB.save(MenuItem('eggs'))

In this example, the provider stores some test data in its DB in order to make the system ready to receive mock calls from the consumer and therefore verify the pact.

Configuration

The default configuration of Pact Test assumes the following values:

  • consumer_tests_path: tests/service_consumers

  • provider_tests_path: tests/service_providers

  • pact_broker_uri: None

It is possible to override such values by creating a file named .pact.json in the project’s root. The following is an example of a valid configuration file:

{
  "consumer_tests_path": "mypath/mytests",
  "provider_tests_path": "mypath/mytests",
  "pact_broker_uri": "http://example.com/"
}

All fields are optional: only specified fields will override default configuration values.

Development

Setup

python3 setup.py install

Test

It is possible to run the tests locally with Docker through the following command:

$ ./bin/test

By default this command tests the library against Python 3.6. It is possible to specify the Python version as follows:

$ ./bin/test <ENV>

Available values for ENV are: py27, py33, py34, py35 py36, py37 and py38. It is also possible to test all the versions at once with:

$ ./bin/test all

Upload New Version

$ python3 setup.py sdist upload

With Python Wheels:

$ python3 setup.py sdist bdist_wheel
$ twine upload dist/*

Release files for pact-test 1.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pact-test 1.0.4
File Size Uploaded
pact-test-1.0.4.tar.gz 18.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pact-test 1.0.4
File Interpreter ABI Platform
pact_test-1.0.4-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 43.2 kB

Release files / pact-test-1.0.4.tar.gz

Download URL pact-test-1.0.4.tar.gz
Size 18.1 kB
Tags Source
SHA-256 checksum
How to use checksums
91b185e188af96de8b0b9e4879fda22c708c9eb1f10967f1b4b06768e23bd404
BLAKE2b-256 checksum
How to use checksums
2814a598404a3b64f90a6cbe6a217240c6aa6b84f25b99dbd7b25089e140f19a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.7.4

Release files / pact_test-1.0.4-py2.py3-none-any.whl

Download URL pact_test-1.0.4-py2.py3-none-any.whl
Size 25.1 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
9c819d778417cc0fdd28a46dc0d553e45d88035de56cde22780a8fa72b109071
BLAKE2b-256 checksum
How to use checksums
b0449769a32588f7f6d8567174b1e035a6a5802da03d01d3d837521c386b0640
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.7.4

Release history Release notifications | RSS feed

This release

1.0.4 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.3.99

2 release files

0.3.98

2 release files

0.3.97

2 release files

0.3.96

2 release files

0.3.95

2 release files

0.3.94

2 release files

0.3.93

2 release files

0.3.92

2 release files

0.3.91

2 release files

0.3.90

2 release files

0.3.89

2 release files

0.3.88

2 release files

0.3.87

2 release files

0.3.86

2 release files

0.3.85

2 release files

0.3.84

2 release files

0.3.83

2 release files

0.3.82

2 release files

0.3.81

2 release files

0.3.80

2 release files

0.3.79

2 release files

0.3.78

2 release files

0.3.77

2 release files

0.3.76

2 release files

0.3.75

2 release files

0.3.74

2 release files

0.3.73

2 release files

0.3.72

2 release files

0.3.71

2 release files

0.3.70

2 release files

0.3.69

2 release files

0.3.68

2 release files

0.3.67

2 release files

0.3.66

2 release files

0.3.65

2 release files

0.3.64

2 release files

0.3.63

2 release files

0.3.62

2 release files

0.3.61

2 release files

0.3.60

2 release files

0.3.59

2 release files

0.3.58

2 release files

0.3.57

2 release files

0.3.56

2 release files

0.3.55

2 release files

0.3.54

2 release files

0.3.53

2 release files

0.3.52

2 release files

0.3.51

2 release files

0.3.50

2 release files

0.3.49

2 release files

0.3.48

2 release files

0.3.47

2 release files

0.3.46

2 release files

0.3.45

2 release files

0.3.44

2 release files

0.3.43

2 release files

0.3.42

2 release files

0.3.41

2 release files

0.3.40

2 release files

0.3.39

2 release files

0.3.38

2 release files

0.3.37

2 release files

0.3.36

2 release files

0.3.35

2 release files

0.3.34

2 release files

0.3.33

2 release files

0.3.32

2 release files

0.3.31

2 release files

0.3.30

2 release files

0.3.29

2 release files

0.3.28

2 release files

0.3.27

2 release files

0.3.26

2 release files

0.3.25

2 release files

0.3.24

2 release files

0.3.23

2 release files

0.3.22

2 release files

0.3.21

2 release files

0.3.20

2 release files

0.3.19

2 release files

0.3.18

2 release files

0.3.17

2 release files

0.3.16

2 release files

0.3.15

2 release files

0.3.14

2 release files

0.3.13

2 release files

0.3.12

2 release files

0.3.11

2 release files

0.3.10

2 release files

0.3.9

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.50

2 release files

0.1.49

2 release files

0.1.48

1 release file

0.1.47

1 release file

0.1.46

1 release file

0.1.45

1 release file

0.1.44

1 release file

0.1.43

1 release file

0.1.42

1 release file

0.1.41

1 release file

0.1.40

1 release file

0.1.39

1 release file

0.1.38

1 release file

0.1.37

1 release file

0.1.36

1 release file

0.1.35

1 release file

0.1.34

1 release file

0.1.33

1 release file

0.1.32

1 release file

0.1.31

1 release file

0.1.30

1 release file

0.1.29

1 release file

0.1.28

1 release file

0.1.27

1 release file

0.1.26

1 release file

0.1.25

1 release file

0.1.24

1 release file

0.1.23

1 release file

0.1.22

1 release file

0.1.21

1 release file

0.1.20

1 release file

0.1.19

1 release file

0.1.18

1 release file

0.1.17

1 release file

0.1.16

1 release file

0.1.15

1 release file

0.1.14

1 release file

0.1.13

1 release file

0.1.12

1 release file

0.1.11

1 release file

0.1.10

1 release file

0.1.9

1 release file

0.1.8

1 release file

0.1.7

1 release file

0.1.6

1 release file

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

2 release files

0.1.1

2 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page