Introduction
This post is a report of my experience trying to go through the Pact.NET Bi-Directional examples (which are compatible to eachother) provided by Pactflow community/team:
Provider example: https://github.com/pactflow/example-bi-directional-provider-dotnet
Consumer example: https://github.com/pactflow/example-bi-directional-consumer-dotnet
I just decided to post this, in case it would be helpful to anybody trying to go through the same examples.
Provider
I’ve been through the pact example in a WSL2 environment.
I made sure that the Pre-requisites are fullfilled in my environment.
This pact example also includes yml files to Create and run GitHub build pipelines. If you want to run GitHub pipelines then you have to fork the pact example to be able to commit and push your changes and to trigger the pipeline.
But to understand the workflow you don’t necessaray have to run those GitHub pipelines. You can just use the makefile commands to see and understand the Pactflow workflow involved in deploying the provider and the consumer.
So to playout the Pactflow workflow I first prepared the environment variables which are required by the makefile commands.
export PACT_BROKER_BASE_URL="https://my-company.pactflow.io"
export PACT_BROKER_TOKEN=my-token
These two variables can be copy pasted from this page of your Pactflow account.
Click on the settings symbol on the top on the right:
![](https://www.iteacorner.com/wp-content/uploads/2022/07/grafik-1-1024x422.png)
Click on the buttons for copying the URL and the read/write token to copy/paste the corresponding value:
![](https://www.iteacorner.com/wp-content/uploads/2022/07/grafik-2-1024x409.png)
Local Testing
As described in on the project documentation I executed the following command to generate the dll for the project and the swagger doc:
make
publish_dll
Then I ran the command to verify the provider API endpoints againt the swagger doc:
make verify_swagger
or make test
(both call the same script: verify_swagger.sh
)
And got the following results:
$ make verify_swagger
./example-bi-directional-provider-dotnet/scripts/verify_swagger.sh
Started dotnet API with process ID: 7620
Running schemathesis test to generate report
Stopping dotnet API
At this point you might have encounted the problem (described here: $GUIDr-E117D8CF-4C16-450A-8ADF-AFF201CE667E), which happened to me because I had missed the above commands and started directly with the make test
command.
The results of the make verify_swagger
(or make test
) command will be written to the report file report.txt
in root folder (see Makefile), which might look like this:
======================= Schemathesis test session starts =======================
Schema location: http://host.docker.internal:9000/swagger/v1/swagger.json
Base URL: http://host.docker.internal:9000/
Specification version: Open API 3.0.1
Workers: 1
Collected API operations: 2
GET /Products . [ 50%]
GET /Products/{id} . [100%]
=================================== SUMMARY ====================================
Performed checks:
not_a_server_error 101 / 101 passed PASSED
status_code_conformance 101 / 101 passed PASSED
content_type_conformance 101 / 101 passed PASSED
response_headers_conformance 101 / 101 passed PASSED
response_schema_conformance 101 / 101 passed PASSED
Hint: You can visualize test results in Schemathesis.io by using `--report` in your CLI command.
============================== 2 passed in 1.06s ===============================
Publishing to Pactflow
Once your local test with make verify_swagger
or make test
is successul you might proceed with publishing the test results to the Pactflow server using the following command, which passes the success code to the docker command for the Pactflow CLI container, which has the tools to execute commands against the Pactflow server:
EXIT_CODE=0 make publish_provider_contract
To understand better what this command is doing, you might check the Makefile:
VERSION?=$(shell npx -y absolute-version)
BRANCH?=$(shell git rev-parse --abbrev-ref HEAD)
OAS_PATH=example-bi-directional-provider-dotnet/swagger.json
REPORT_PATH?=report.txt
REPORT_FILE_CONTENT_TYPE?=text/plain
VERIFIER_TOOL?=schemathesis
...
publish_provider_contract:
@echo "\n========== STAGE: publish-provider-contract (spec + results) ==========\n"
${PACTFLOW_CLI_COMMAND} publish-provider-contract \
${OAS_PATH} \
--provider ${PACTICIPANT} \
--provider-app-version ${VERSION} \
--branch ${BRANCH} \
--content-type application/yaml \
--verification-exit-code=${EXIT_CODE} \
--verification-results ${REPORT_PATH} \
--verification-results-content-type ${REPORT_FILE_CONTENT_TYPE}\
--verifier ${VERIFIER_TOOL}
...
Its important to understand that the publish_provider_contract
command publishes two “things”:
- The swagger.json file and
- The results of actual test involving HTTP requests.
After executing the publish_provider_contract
command, the pact is published on the Pactflow Server:
![](https://www.iteacorner.com/wp-content/uploads/2022/07/grafik-3-1024x482.png)
Remark:
It might be a bit confusing why we would need to publish both the swagger.json and the test results to Pactflow. In fact you could leave out the test result in which case your contract would look like the following example, a contract with swagger data but without results:
![](https://www.iteacorner.com/wp-content/uploads/2022/08/grafik-1-1024x511.png)
can_i_deploy and deploy
After the pact is published to Pactflow, we can use the can_i_deploy
command to check whether the provider can be published, which should be possible, because their is no consumer yet deployed which could be incompatible to provider:
make can_i_deploy
Then we can use the deploy
option to record the deployment of the provider:
make deploy
Consumer
Also on the consumer side we can just clone the repository from github and test the makefile commands locally without any pipeline. Because to understand the Pact workflow we don’t really need the pipeline. Of course we can also fork the repository and trigger our own github pipeline by committing changes to our repository, but lets just leave out the pipeline and just work locally:
git clone https://github.com/pactflow/example-bi-directional-consumer-dotnet.git
Make sure that the environment variables are set, just like explained in the provider section:
export PACT_BROKER_BASE_URL="https://my-company.pactflow.io"
export PACT_BROKER_TOKEN=my-token
On the consumer side we need another environment variable to pass the name of the provider:
export PACT_PROVIDER=pactflow-example-bi-directional-provider-dotnet
Local Testing
Run the pact unit tests:
make test
That step generates the pact file.
Next we have to publish the pact file. The makefile offers the command make fake_ci
which sets all required parameters, publishes the pact file and also executes the can_i_deploy step:
make fake_ci
...
ci: test publish_pacts can_i_deploy $(DEPLOY_TARGET)
# Run the ci target from a developer machine with the environment variables
# set as if it was on CI.
# Use this for quick feedback when playing around with your workflows.
fake_ci:
@CI=true \
GIT_COMMIT=`git rev-parse --short HEAD`+`date +%s` \
GIT_BRANCH=`git rev-parse --abbrev-ref HEAD` \
REACT_APP_API_BASE_URL=http://localhost:8080 \
make ci
publish_pacts:
@echo "\n========== STAGE: publish pacts ==========\n"
@"${PACT_CLI}" publish ${PWD}/tests/pacts --consumer-app-version ${GIT_COMMIT} --branch ${GIT_BRANCH}
...
Troubleshooting
Error: “dotnet: command not found”
$GUIDi-E117D8CF-4C16-450A-8ADF-AFF201CE667E
Problem
Under provider, after running the following command:
make test
The following error is issued:
./example-bi-directional-provider-dotnet/scripts/verify_swagger.sh
Started dotnet API with process ID: 1263
Running schemathesis test to generate report
Unable to find image 'schemathesis/schemathesis:stable' locally
./example-bi-directional-provider-dotnet/scripts/verify_swagger.sh: line 3: dotnet: command not found
stable: Pulling from schemathesis/schemathesis
...
Status: Downloaded newer image for schemathesis/schemathesis:stable
Stopping dotnet API
./example-bi-directional-provider-dotnet/scripts/verify_swagger.sh: line 13: kill: (1263) - No such process
make: *** [Makefile:81: test] Error 1
Resolution
Make sure that dotnet SDK is installed in your WSL/Ubuntu environment.
First enable Microsoft PPA:
$ wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb $ sudo dpkg -i packages-microsoft-prod.deb
Then install the dotnet SDK:
$ sudo apt update
$ sudo apt install apt-transport-https
$ sudo apt install dotnet-sdk-3.1
This is because the command dotnet build
was not executed yet and as a result the provider .NET project is not yet built. In my case, this was because I hadn’t executed the following commands before executing make test:
make publish_dll
make verify_swagger
Now the test command should work:
make test