Skip to content

Commit ccb09e4

Browse files
authored
Set up working example of py wiremock (#59)
* Set up working example of py wiremock This commit introduces a new "example" directory that demonstrates how to use python-wiremock for testing against a http service. The idea behind this example is two fold. 1) provide some exspansive real world working examples of using wiremock 2) develop a real world application using all of wiremocks features to aid with e2e testing. The example directory builds a few python services using fast api which are built and run using docker. The two services Overview Service and Products Service in the example app communicate with eachother via http. The test suite in the example app then demonstrates how to use wiremock to stub responses from Products Service so that Overview Service can be tested more easily without needing to run Product Service.
1 parent 579de86 commit ccb09e4

File tree

15 files changed

+1011
-19
lines changed

15 files changed

+1011
-19
lines changed

.github/workflows/tests.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Python Testing
1+
name: CI
22

33
on:
44
push:
@@ -7,7 +7,7 @@ on:
77
branches: [master]
88

99
jobs:
10-
build:
10+
unit-tests:
1111
runs-on: ubuntu-latest
1212

1313
strategy:
@@ -31,4 +31,17 @@ jobs:
3131
3232
- name: Test with pytest
3333
run: |
34-
poetry run pytest
34+
poetry run pytest tests/
35+
36+
integration-tests:
37+
runs-on: ubuntu-latest
38+
needs: [unit-tests]
39+
40+
steps:
41+
- uses: actions/checkout@v3
42+
43+
- name: Integration Tests
44+
run: |
45+
cd example/
46+
docker-compose build overview_srv
47+
docker-compose run overview_srv pytest --tb=short

example/.flake8

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[flake8]
2+
ignore = E203, E266, E501, W503, F403
3+
max-line-length = 88
4+
max-complexity = 18
5+
select = B,C,E,F,W,T4,B9

example/Dockerfile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# vim: set filetype=Dockerfile:
2+
FROM python:3.11-slim-buster
3+
4+
ENV POETRY_HOME="/opt/poetry" \
5+
POETRY_VIRTUALENVS_CREATE=false \
6+
POETRY_NO_INTERACTION=1
7+
8+
# Prepend poetry and venv to path
9+
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"
10+
11+
RUN apt-get update && apt-get install --no-install-recommends -y curl default-jre-headless \
12+
&& curl -sSL https://install.python-poetry.org | python
13+
14+
# Update poetry to latest version
15+
RUN poetry self update
16+
17+
WORKDIR /app/example
18+
19+
# Install dependencies
20+
COPY . /app
21+
COPY ./example/pyproject.toml ./example/poetry.lock /app/example/
22+
RUN poetry config virtualenvs.create false \
23+
&& poetry install --no-root --no-interaction --no-ansi
24+
25+
26+
# Copy the rest of the application code
27+
COPY ./example /app/example
28+
29+
# Expose the port that the FastAPI app will listen on
30+
EXPOSE 5001
31+
EXPOSE 5002
32+
33+
CMD ["python"]

example/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Python Wiremock Example
2+
3+
## Introduction
4+
5+
This example code demonstrates usage of python wiremock. The example code demonstrates a fictional set of microservices
6+
where the `overview_service` depends on the display of products returned from the `products_service`.
7+
8+
When the services are run normally the Overview service makes a request to the Products services and the list of
9+
products returned by the Product Service is displayed to the user.
10+
11+
```
12+
+-----------------+ +-----------------+
13+
| Overview Service| | Products Service|
14+
+-----------------+ +-----------------+
15+
| |
16+
| GET /products |
17+
|--------------------------------->|
18+
| |
19+
| List of products |
20+
|<---------------------------------|
21+
| |
22+
| Display products to user |
23+
|--------------------------------->|
24+
| |
25+
```
26+
27+
When we are writing tests to ensure that the Overview Service works correctly, we do not want to have the overview service
28+
have to depend on real requests being made to the products services. This normally leads to the code being mocked, and other approaches that
29+
are hard to maintain and dont allow us to test the code closer to real world conditions.
30+
31+
Ultimately, we want a real http request to happen under test conditions so that the tests and the code operate as if the products
32+
services is running and returning actual http responses. In tests we also need to be able to control what this system returns
33+
so that we can assert the code acts in certain ways when it gets certain responses from the server.
34+
35+
This is what python-wiremock helps to solve.
36+
37+
The example code demonstrates how to use python-wiremock to run a test server directly from our tests that give us
38+
full control over how the mock service should handle our requests. We can generate respones directly from the tests
39+
to allow us to write solid integration tests that dont involved mockig the code we're trying to test.
40+
41+
## Running the tests
42+
43+
To run the tests use docker-compose to create the necessary containers.
44+
45+
`docker-compose run overview_srv pytest --tb=short`
46+
47+
## How we use this example code base
48+
49+
As well as serving as a working example of how to work with python wiremock, this example code base is also used as a "e2e" test suite of sorts.
50+
The docker-compose configuration bundles the python-wiremock code directly into the container so that we can actually iterate on changes against a
51+
real world example.

example/docker-compose.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: "3"
2+
3+
services:
4+
overview_srv:
5+
build:
6+
context: ../
7+
dockerfile: example/Dockerfile
8+
ports:
9+
- "5001:5001"
10+
volumes:
11+
- ..:/app/
12+
- .:/app/example/
13+
command: uvicorn product_mock.overview_service:app --host=0.0.0.0 --port=5001
14+
15+
products_srv:
16+
build:
17+
context: ../
18+
dockerfile: example/Dockerfile
19+
ports:
20+
- "5002:5002"
21+
volumes:
22+
- ..:/app/
23+
- .:/app/example/
24+
command: uvicorn product_mock.products_service:app --host=0.0.0.0 --port=5002

0 commit comments

Comments
 (0)