You have spent six chapters learning every layer of microservices testing — component tests with WireMock and Testcontainers, consumer-driven contracts with Pact, integration tests with Docker Compose, resilience testing with Toxiproxy, observability assertions, Kafka consumer tests, eventual consistency patterns, and saga compensation. This capstone brings every technique together into a single, realistic system. Your job is not to read and move on — it is to design and build a complete test strategy for a production-grade order management platform, then implement the most critical pieces from scratch.
The system you are testing
The platform consists of six services communicating over HTTP and Kafka, each with its own PostgreSQL database:
User Service — registration, login, JWT issuance, profile management. All other services call it to resolve user identity.
Product Service — product catalog, inventory tracking, stock reservation. Exposes /products/{id} and /products/{id}/reserve.
Order Service — the system's orchestrator. Handles cart, checkout, and the full order lifecycle (PENDING → CONFIRMED → SHIPPED → DELIVERED). Calls User Service and Product Service synchronously. Publishes order.created, order.cancelled, and order.refund_requested events to Kafka.
Payment Service — processes charges and refunds. Called synchronously by Order Service during checkout. Publishes payment.succeeded and payment.failed to Kafka.
Notification Service — listens for Kafka events and sends email and SMS. Non-critical: a Notification Service failure must not affect order processing.
Reporting Service — consumes events from all services and materialises aggregated views. Reads are eventually consistent; reports may lag by up to 30 seconds.
- – Component tests
- – Pact provider
- – Component tests
- – Pact provider
- – Component + contract tests
- – Integration tests
- – Saga tests
- – Chaos + circuit breaker
- – Pact provider
- Kafka consumer tests –
- Non-critical path tests –
- Eventual consistency tests –
- E2E report assertions –
Your deliverables
Work through these in order — each builds on the last.
1. Test strategy document
Before writing a single test, write a one-page strategy that answers: how many tests of each type for each service? For the Order Service (the orchestrator), your pyramid should be heavily weighted toward component and contract tests, with a small integration suite and only 3–5 E2E tests covering the most critical user journeys. For stateless services like Notification, unit tests plus a Kafka consumer test may be sufficient.
Explicitly call out which flows are covered at each level. "Place order" should appear at the component level (Order Service tests with WireMock), the integration level (real services + Kafka), and the E2E level (Playwright from browser to confirmation page). "Send notification email" only appears at the Kafka consumer test level — not in E2E.
2. Component test suite for Order Service
Implement a full @SpringBootTest class with:
PostgreSQLContainerfor Order Service's own databaseWireMockServerstubs for User Service, Product Service, and Payment ServiceKafkaContainerto verify thatorder.createdis published when an order succeeds- At minimum: happy-path create, out-of-stock path, payment failure path, order cancellation
Use @DynamicPropertySource to wire all containers into the Spring context. Use dynamicPort() for all WireMock servers.
3. Pact contract tests
Write consumer tests from Order Service's perspective against User Service and Product Service. For each:
- Define the interaction using
LambdaDslmatchers, not hardcoded values - Publish the generated pact to your local Pact Broker (or a file-based broker for local dev)
- Write the provider verification tests on the User Service and Product Service side
- Run
can-i-deployas a CI gate before any service deployment
4. Docker Compose integration environment
Write docker-compose.test.yml that starts all six services, a Kafka broker, and six PostgreSQL instances. Every service must declare a healthcheck and all depends_on must use condition: service_healthy. The environment must be fully self-contained — no external calls, no shared staging databases.
5. Integration tests for critical flows
Using ComposeContainer, write two integration tests:
- Place order: POST a checkout request, poll until order status is CONFIRMED, verify inventory was decremented on Product Service, verify
order.createdwas published to Kafka - Refund: request a refund on a delivered order, verify Payment Service processed it, verify
order.refund_requestedwas published
6. Saga tests
Order placement is a saga: reserve inventory → charge payment → confirm order. If payment fails, inventory must be released. Test three scenarios:
- Happy path: all steps succeed, order reaches CONFIRMED
- Payment failure: payment returns 402, verify inventory is released and order reaches CANCELLED
- Notification failure: Notification Service is down, verify order still reaches CONFIRMED (non-critical dependency)
7. Chaos test — circuit breaker on Payment Service
Using Toxiproxy, inject 3-second latency into the connection between Order Service and Payment Service. Configure Order Service's circuit breaker with a 1-second timeout and 3-call threshold. Submit four rapid checkout requests and assert:
- First three fail with
503 Service Unavailable(circuit breaker trips after timeout) - Fourth fails immediately (circuit is OPEN — no attempt to Payment Service)
- Remove the toxic, wait for the half-open window, submit one more request — circuit closes
8. Five E2E tests (Playwright)
Cover these journeys and only these:
- Register → browse → add to cart → checkout → confirm order
- Login → view order history → request refund → verify refund status
- Admin: view real-time order report (verifies Reporting Service)
- Browse out-of-stock product → attempt checkout → receive clear error
- Failed payment → retry with different card → confirm order
9. Distributed tracing assertions
Add a test that places an order, extracts the X-Request-ID from the response header, queries Jaeger's API for that trace, and asserts that spans exist for all four synchronous service calls (Order → User, Order → Product, Order → Payment, Order → self for DB write).
10. CI/CD pipeline
Write a GitHub Actions workflow with four jobs:
fast-tests: component tests + Pact tests, runs on every PR, target < 3 minutesintegration-tests: Docker Compose suite, runs on every PR, target < 10 minuteschaos-tests: Toxiproxy resilience suite, scheduled weeklye2e-tests: Playwright suite, scheduled nightly
Every job that deploys a service must call can-i-deploy before promoting to the next environment.
⚠️ Common mistakes
- Skipping the strategy document and jumping straight to code. The strategy document forces you to decide what is worth testing at each level before you are three days into writing component tests for Notification Service (which barely needs any). The document is not busywork — it is the map that stops you spending a week in the wrong place.
- Making Notification Service critical in your test setup. Notification Service is explicitly non-critical. If your Docker Compose integration tests fail because the Notification Service container crashes, you've encoded a false dependency. Tests that verify non-critical services should use separate failure scenarios, not block the critical path suite.
- Testing every service at every layer. The Reporting Service has no synchronous callers and no saga participation. It needs: a Kafka consumer test, an eventual consistency test, and one E2E test that reads a report. It does not need component tests with WireMock — there is nothing to stub. Apply the pyramid proportionally per service.
🎯 Practice task
Before moving to the walkthrough, spend 45 minutes on this planning step:
- Draw the system. Sketch the six services on paper — boxes for services, arrows for synchronous HTTP calls, dashed arrows for Kafka events. Label each arrow with the endpoint or event name.
- Annotate test types. Next to each service box, write which test types apply: component, contract (consumer? provider? both?), integration, chaos, E2E. The Order Service should have all five. The Notification Service should have two.
- Count your tests. For the Order Service specifically, estimate: how many component tests? How many Pact consumer interactions? How many integration test scenarios? How many E2E tests? A reasonable starting target: 15–20 component tests, 6–8 Pact interactions, 3–4 integration scenarios, 2 E2E tests.
- Identify the riskiest integration. Which service-to-service call, if it broke silently, would cause the most business harm? That is where you invest your contract tests first and your chaos engineering second.
- Write your strategy document. One page, bullet points, per-service breakdown. Keep it — you will need it to self-assess in Lesson 3.