Package: pact-test
Pact Test for PythonThis repository contains a Python implementation forPact. 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 thePact 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…InstallationPact Test is distributed throughPyPiso it can be easily included in therequirements.txtfile or normally installed withpip:$pipinstallpact-testProviders Tests (Set the Contracts)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 athere. Consumers define
all the interactions with their providers in the following way:@service_consumer('PythonEats')@has_pact_with('PyzzaHut')classPyzzaHutTest(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'}})deftest_get_pepperoni_pizza(self):pizza=get_pizza('pepperoni')assertpizza['id']==42assertpizza['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 unhappy404situation:@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'}})deftest_get_hawaiian_pizza(self):pizza=get_pizza('hawaiian')assertpizza.status_code==404assertpizza.json()['message']=='we do not serve pineapple with pizza'Consumers Tests (Honour Your Contracts)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:Djanjo (TODO)FlaskPyramidThere are few things required to setup and run consumer tests.Pact HelperThis 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:classRestaurantPactHelper(PactHelper):process=Nonedefsetup(self):self.process=subprocess.Popen('gunicorn start:app -w 3 -b :8080 --log-level error',shell=True)deftear_down(self):self.process.kill()There are few rules for the helper:itmustextendPactHelperclass frompact_testitmustdefine asetupmethoditmustdefine atear_downmethodIt is also possible to override default url (localhost) and port (9999):classRestaurantPactHelper(PactHelper):test_url='0.0.0.0'test_port=5000StatesWhen 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')classUberEats(ServiceConsumerTest):@state('some menu items exist')deftest_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.ConfigurationThe default configuration of Pact Test assumes the following values:consumer_tests_path:tests/service_consumersprovider_tests_path:tests/service_providerspact_broker_uri:NoneIt is possible to override such values by creating a file named.pact.jsonin 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.DevelopmentSetuppython3setup.pyinstallTestIt is possible to run the tests locally with Docker through the following command:$./bin/testBy 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 forENVare:py27,py33,py34,py35py36,py37andpy38. It is also possible to test all the versions at once with:$./bin/testallUpload New Version$python3setup.pysdistuploadWithPython Wheels:$python3setup.pysdistbdist_wheel$twineuploaddist/*