Used this repo as a sandbox to explore Pact for Python. Goal was to figure out if it was suitable & beneficial to integrate this type of testing into my team's CI/CD pipeline. Now it serves as an introductory demo.
"Contract testing is a technique for testing an integration point by checking each application in isolation to ensure the messages it sends or receives conform to a shared understanding that is documented in a "contract".
For applications that communicate via HTTP, these "messages" would be the HTTP request and response, and for an application that used queues, this would be the message that goes on the queue.
In practice, a common way of implementing contract tests (and the way Pact does it) is to check that all the calls to your test doubles return the same results as a call to the real application would." - Quoted from Pact's official website.
(Note that this demo does not connect to an actual database, the database clipart in the diagram just signifies where one would be connected to)
- Endpoint receives a name which will be sent as a request to Api_Gateway, which is supposed to respond with its corresponding number cube-squared
- If the endpoint receives a name 'bob' which corresponds to '3' in the database, it should return 3^3^2 which is 729
- Receives a name from Frontend which will be sent as a request to Database, responding with its corresponding number
- The response number will be sent as a request to Worker to be cubed
- The response cubed number will be sent as a request to Worker to be squared
- The response cubed then squared number will be returned as a response back to Frontend
- Receives a name from Api_Gateway which will return with the name's corresponding number if available
- If the database is
{"bob": 3}
and it receives a request of "bob", it will return a response of "3"
- If the database is
- Receives a number from Api_Gateway and depending on the endpoint called, it will either:
- Return a response of the number squared
- Return a response of the number cubed
Each of the services will be hosted on Uvicorn and are designed to communicate via FastAPI.
The Pact broker server(if utilized) will be in a dockerized container.å
- Python v3.11 (some minor versions below may work, but they weren't tested) for direct testing
- Docker engine for testing on docker containers
- To run the tests directly on your machine, you would need to first install the required python packages:
$ pip install -r requirements-dev.txt
- To run the tests via prepared docker containers, first ensure you have the docker engine up and running
- If simulating with a broker is desired, ensure docker engine is up and running. Then enter the 'broker' directory and run:
This will pull and run the broker service in docker containers
$ docker-compose up
-
Running pact test on a service:
By default, pact contracts will be handled locally in the 'pacts' directory. This directory will automatically be created in the 'contract' directory once you have run a test that includes consumer testing.
To run the pact tests (both consumer & provider if available) on an individual service, run its testing script:
$ ./tests/contract/pact_test_{x}.sh
(replace
{x}
with service name)If the script files cannot be found/accessed, ensure you have permissions to execute it by running:
$ chmod +x tests/contract/pact_test_{x}.sh
(replace
{x}
with service name) -
The results of the consumer test will be output to the terminal. To see the generated contracts, you may check the 'pacts' directory or the pact broker server(accessible via web browser) to see the created contract(s). The contract file should look something like
{consumer}-{provider}.json
-
The results of the provider verification will be output to the terminal. If published to the pact broker server, it will now show the new verification status of the contract(as seen when accessing via web browser).
-
Selecting the service to test
You may change the
SERVICE
constant indocker_pact.sh
to any one of the services in 'src' by name (excluding the file extension '.py') -
Run the docker test container script
Simply run the script to start the testing process:
$ ./tests/docker_pact.sh
If the script files cannot be found/accessed, ensure you have permissions to execute it by running:
$ chmod +x tests/docker_pact.sh
-
The results of the consumer test will be output to the terminal. To see the generated contracts, you may check the 'pacts' directory or the pact broker server(accessible via web browser) to see the created contract(s). The contract file should look something like
{consumer}-{provider}.json
-
The results of the provider verification will be output to the terminal. If published to the pact broker server, it will now show the new verification status of the contract(as seen when accessing via web browser)
-
The docker logs will be saved at the end of the testing process. It will be saved in 'tests/contract/log' as
pact-docker.log
By default, the pact contracts will be stored locally in the 'tests/contract/pacts' folder. If you wish to use the pact broker server to handle your pact contracts for you, make these changes before running any script to allow it to communicate with the broker server:
-
Make sure the broker service is already set up as shown in the environment setup section
-
When testing a service {x} as a consumer, you may change the
PACT_BROKER_PUBLISH
constant intest_{x}-{y}.py
to True/False whether you want to publish it to your broker server. -
When verifying service {x} as a provider, you may add a provider version as an argument of the script (e.g.
./tests/contract/pact_test_{x}.sh 1.0.0
) which will verify the latest contract using pact broker instead of the local contract.