Contract testing with WireMock<br>Aug 8, 2026<br>Contract testing with WireMock
Have you ever come across a codebase with thousands of unit and integration tests, and still lacked confidence that what you pushed to production would not break a happy path or introduce a regression?
Modern applications consume many third-party APIs. Unit tests and integration tests that rely on hand-rolled mocks often are not enough. WireMock lets you stub third-party HTTP request/response pairs with your own datasets and fixtures. Build those fixtures from real application traffic—pulled from monitoring tools or your database—so you exercise production-like paths and edge cases and catch regressions earlier.
These tests move you closer to confident deploys because they run real production code paths end to end inside your service, not just isolated methods, using examples taken from logs and monitoring.
WireMock is not a replacement for fast unit tests that stub a client method in-process, and it is not a full end-to-end test against live production providers. Use it when you want to exercise real production paths against your codebase in isolation.
Key benefits
Complete isolation: Run tests locally or in CI without depending on flaky or unreleased third-party systems.
Fault and error simulation: Force HTTP error codes (400, 404, 500) and network timeouts to validate resilience.
Request verification: Capture incoming requests so you can assert that your app sent the correct parameters, headers, or payloads.
Stateful behavior: Mock multi-step workflows (e.g. “pending” on the first call, “complete” on the second).
Record and playback: Capture traffic from real APIs to generate reusable stubs.
Sample stack
WireMock — HTTP stubbing at the wire level
Docker — same WireMock process in local runs and CI
pytest — fixtures to check the container and point the app at it
Why this combo
Stub path, method, headers, and body without touching production APIs
Replay recorded traffic or load fixtures from production-like JSON
Keep local and CI environments aligned via a container image
Keep tests readable: pytest owns lifecycle; WireMock owns HTTP behavior
Project tree (docker-compose)
Keep WireMock stubs next to the app and mount them into the container. Know this layout before you scaffold files:
├── .github/<br>│ └── workflows/<br>│ └── test.yml # start WireMock → pytest → tear down<br>├── docker-compose.yml # WireMock service + volume mounts<br>├── requirements-dev.txt # or pyproject.toml — pytest, requests, …<br>├── pytest.ini<br>├── src/<br>│ └── myapp/ # your Python service / client under test<br>│ └── clients/<br>│ └── orders.py # talks to ORDERS_API_BASE_URL<br>├── tests/<br>│ ├── conftest.py # pytest fixtures (WireMock URL, app client)<br>│ └── test_orders.py # integration tests against stubs<br>└── wiremock/ # everything WireMock loads at startup<br>├── mappings/ # request → response rules (JSON)<br>│ ├── get-order-123.json<br>│ └── get-order-404.json<br>└── __files/ # response bodies referenced by mappings<br>└── orders/<br>├── order-123.json # happy-path payload (real-world sample)<br>└── order-missing.json
Path<br>Role
docker-compose.yml<br>Starts WireMock and mounts wiremock/ into the container
wiremock/mappings/<br>Stub definitions (method, URL, matchers, status, which body file)
wiremock/__files/<br>HTTP response bodies; bodyFileName is relative to this folder
tests/conftest.py<br>Points the app at http://localhost:8080 (or compose DNS in CI)
src/myapp/<br>Real code under test — no knowledge of WireMock, only the base URL
WireMock’s container paths are fixed: host ./wiremock/mappings → /home/wiremock/mappings, and ./wiremock/__files → /home/wiremock/__files.
Setup guide: from scratch
End-to-end path to get your first WireMock + pytest test green. Do these steps in order.
1. Install prerequisites
Tool<br>Why<br>Check
Python 3.11+<br>App + pytest<br>python3 --version
Docker Desktop (or Engine + Compose plugin)<br>Runs the WireMock container<br>docker --version and docker compose version
Git (optional)<br>Version stubs with the app<br>git --version
You do not install a WireMock JAR or Java locally — the official image provides WireMock inside Docker.
2. Create a virtualenv and install test deps
python3 -m venv .venv<br>source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install pytest requests<br># optional but common: httpx, pytest-dotenv<br>Minimal requirements-dev.txt:
pytest>=8.0<br>requests>=2.31<br>3. Scaffold directories
mkdir -p src/myapp/clients tests wiremock/mappings wiremock/__files/orders<br>Point your HTTP client at a configurable base URL (e.g. ORDERS_API_BASE_URL). Tests will override it to WireMock; production keeps the real host.
4. Add docker-compose and WireMock stubs
Create docker-compose.yml at the repo root:
services:<br>wiremock:<br>image: wiremock/wiremock:3.9.1<br>ports:<br>- "8080:8080"<br>volumes:<br>- ./wiremock/mappings:/home/wiremock/mappings<br>- ./wiremock/__files:/home/wiremock/__files<br>healthcheck:<br>test: ["CMD", "curl", "-f", "http://localhost:8080/__admin/mappings"]<br>interval:...