Webhook Mock Service in Python
Distributed software systems offer new and exciting challenges for test automation. A product is not encapsulated in one giant software product, but scattered among professionalized services. Even when your project is not a highly micronized service landscape you often have the challenge: How to verify that the system under test sent out the correct message?
There are possible solutions for this challenge. One is to deploy more than only the system under test (SUT), but also its involved services. But then you rely on those services exposing the received message. Maybe they don’t. Also since every service is connected with more services you might end up with a complex mess of services you need to maintain in your test infrastructure. And some you might not even need for your test scenarios.
Of course, I agree with you, when you argue, you should not need to know the exact message being exchanged between services. If you consider the whole service mesh as a black box that you feed with a certain input and get the expected output, you likely do not need to validate the intermediate messages.
Also, when testing compatibility of microservices, you probably are better of with contract testing, making every microservice pipeline aware when API specifications break.
However, there are occasions when you just want to know: does the SUT send out the right message? Either because your receiving service is chat-ops or because your setup justifies a “shortcut” instead of managing API contracts or major infrastructure deployments. And the shortcut looks like this:
This WebhookMock service accepts POST requests on any endpoint and caches them. With GET requests on the same endpoint you receive all payloads from previous requests.
All you need is:
- Python (I tested with Python 3.8 and 3.9)
- Install dependencies with :
pip install fastapi
- Download the above python script WebhookMock.py
- Run the WebhookMock service:
python WebhookMock.py
The webservice should greet you in your browser on http://localhost:8000/
If you call http://localhost:8000/all you get all payloads received on all endpoints. At the beginning, you did not receive anything yet, thus the result is empty.
Now you can charge you Postman, javascript or favorite REST testing tool and fire POST requests against any endpoint (except against root and /all ).
Make GET requests on various endpoints and see how the results behave. Imagine how can verify messages sent to this webservice by a SUT that you configure to send message to this WebhookMock instead of the real service.
Naturally, I cannot go without my favorite test automation framework, so here comes the out-of-the-box running demo with Robot Framework:
As always, the test cases are self explaining. The first one sends pure text messages to the WebhookService, the second one a JSON payload. You can also mix the message types. In its current implementation, the WebhookService expects text or JSON.
In order to run these test cases, you
- need to install the dependencies for this test case:
pip install robotframework robotframework-requests
2. Download the above robot test case file WebhookMockTests.robot
3. Run
robot WebhookMockTests.robot
Keep in mind, the WebhookMock service must still be running. Check in the generated log.html how the interaction with the Webhook service went.
Of course you can use any other test framework in any language for accessing the WebhookMock service.
This code snippet would not be possible without my friends and opensource enthusiasts Nils Balkow-Tychsen and Humanitec who made most of the work by implementing the initial approach based on Flask.
Since I had slightly different requirements and I am not used to Flask, therefore I created this fork porting it to FastAPI.
By the way, if you are an API developer who does not have the resources for maintaining excessive cloud architecture, checkout the self-service platform from Humanitec on https://humanitec.com which enables convenient deployments on cloud infrastructure.