You have now designed and implemented a production-grade test strategy for a six-service order management system. Before moving on, this lesson gives you a structured self-assessment to verify your work is genuinely complete, six stretch goals that will sharpen your expertise beyond what most engineers ever attempt, and a clear picture of where microservices testing expertise fits in a QA career. This is not a summary of what you learned — it is a map of what comes next.
Self-assessment checklist
Work through this list honestly. For any item you cannot check off, return to the relevant lesson before claiming completion.
Strategy
- Written a per-service test strategy document allocating test types for all six services
- Explicitly identified which flows are covered at the component level vs integration level vs E2E level
- Called out which dependencies are critical vs non-critical and reflected that in your test design
Component tests
- Order Service
@SpringBootTestclass starts successfully with PostgreSQLContainer + KafkaContainer + 3 WireMock servers - Happy-path test asserts on HTTP response status, response body fields, and database row existence
- Payment failure test verifies both the order's terminal status and the inventory compensation call via WireMock verify
- Notification-down test confirms the non-critical dependency does not affect the order outcome
- All WireMock servers use
dynamicPort()— no hardcoded ports that break parallel CI
Contract tests
- Pact consumer test for Order → User Service uses
LambdaDslmatchers, not exact values - Pact consumer test for Order → Product Service covers at least the reserve endpoint
- Provider verification tests exist on both User Service and Product Service
-
can-i-deployruns in CI before any service is promoted to staging
Integration and saga tests
-
docker-compose.test.ymlhas healthchecks on every service and alldepends_onusecondition: service_healthy - Place-order integration test polls with Awaitility until the order reaches CONFIRMED
- Saga compensation test verifies inventory is released when payment fails
- Notification failure test runs in isolation (not as part of the Docker Compose suite)
Resilience
- Toxiproxy chaos test injects latency and verifies the circuit breaker transitions from CLOSED → OPEN
- Fast-fail assertion confirms the fourth request completes in under 200ms
- Recovery test confirms the circuit closes after the wait duration
Observability
- Place-order request carries a traceable request ID
- Jaeger (or a compatible tracer) captures spans for all four synchronous downstream calls
- At least one test queries the tracing backend to assert span existence
CI pipeline
- Component + Pact tests run on every PR
- Integration tests run on every PR
- Chaos tests are scheduled (not blocking the PR)
- E2E tests are scheduled nightly (not blocking the PR)
-
can-i-deploygates every environment promotion
Stretch goals
These six goals push beyond what most professional QA teams implement. Attempting even two of them in a real project will put you in the top tier of microservices testing practitioners.
1. Performance tests for each service with K6
Add a K6 load test per service that runs in CI against the Docker Compose environment. Each test should define a steady-state SLO: for example, the Order Service must handle 100 requests/second with p99 latency under 500ms. Fail the pipeline if the SLO is breached. This catches performance regressions before they reach staging — the most common source of incidents in high-throughput microservices systems.
2. Security scans with OWASP ZAP
Run an OWASP ZAP passive scan against the compose environment during the integration test phase. Configure ZAP to fail on high-severity findings (authentication bypass, SQL injection, exposed sensitive headers). Add suppressions for known acceptable risks with documented justifications — suppression without justification is a security debt that gets forgotten.
3. Observability assertions in tests
Add a test fixture that collects all log output from all services during a test run and asserts there are no ERROR or EXCEPTION log entries during happy-path scenarios. Use Loki's query API: {service="order-service"} |= "ERROR" over the test run time window. A happy path that generates error logs is a silent bug — the test passes, the metrics degrade, and the on-call engineer gets paged at 3am.
4. can-i-deploy gates in every environment tier
Extend the CI pipeline to gate staging → production promotion with can-i-deploy for every participating service, not just Order Service. This requires publishing pacts from all consumer services and running provider verification on all provider services. The investment is high but the payoff is a deploy pipeline where breaking a contract is a hard failure, not a post-deploy incident.
5. Canary deployment with automated rollback
Add a canary stage after the integration test job: deploy Order Service at 5% traffic, run the E2E suite against the canary, and assert on error rate metrics from Prometheus (target: < 0.1% 5xx responses). If the assertion fails, trigger an automated rollback by re-deploying the previous image tag. This is the pattern that enables true continuous deployment — the test suite becomes the deployment gatekeeper, not a human approver.
6. Multi-region failover testing
Write a test that simulates a full availability zone failure by stopping all containers in the "primary region" (one Docker network), verifying that the "secondary region" (a second Docker network with replica containers) serves traffic within a defined recovery time objective, and confirming that no orders were lost using the database consistency checks from Lesson 1. This is chaos engineering at the infrastructure level — beyond what most teams test explicitly, and exactly the kind of test that prevents a public incident.
- – K6 load testing
- – JMeter for services
- – Gatling for Scala shops
- – OWASP ZAP automation
- – API security scanning
- – Dependency vulnerability checks
- – Advanced pipeline patterns
- – Test parallelisation
- – Artifact promotion gates
- OpenTelemetry deeper dive –
- SLO-based alerting –
- Chaos engineering maturity –
- Microservices test design –
- Platform test engineering –
- Test infrastructure ownership –
Where to go next
Performance Testing (K6 / JMeter) — The next high-value skill after microservices testing. Every component test you wrote in this course runs at concurrency 1. Performance tests reveal how the system behaves at concurrency 50, 500, or 5000. Load tests that target individual services (not just the front door) are a direct extension of the component testing pattern you now know.
CI/CD for QA Engineers — This course covered the what of pipeline structure. The CI/CD course covers the how: test parallelisation strategies, artifact promotion patterns, test result aggregation across a monorepo, and the operational side of maintaining a test infrastructure that other teams depend on.
Test Automation Frameworks — If you came to this course from a UI automation background, revisit the frameworks course with fresh eyes. The layered architecture principles, separation of concerns, and configuration management patterns from that course apply directly to how you structure a microservices test project with multiple test types across multiple services.
Cloud-native testing patterns — Kubernetes-native testing with tools like Telepresence (intercept live cluster traffic for local development), Testkube (run tests inside the cluster), and Argo Rollouts (canary and blue-green with automated analysis) are the frontier of this discipline. They build directly on what you learned here.
Career relevance
Microservices testing is one of the most senior and least-saturated skills in software quality engineering. Most QA engineers are proficient at UI automation. A smaller number can write API tests. A much smaller number understand component testing, consumer-driven contracts, and chaos engineering at the depth this course requires. That gap is where your career value lives.
The roles where this expertise is decisive:
Senior QA Engineer / SDET — Companies building distributed systems are actively looking for engineers who can own the test strategy for a service, not just write tests against a finished UI. The skills in this course — Testcontainers, WireMock, Pact, Resilience4j testing — are the exact skills that separate a mid-level from a senior QA hire at organisations running microservices.
Test Architect — Test architects design testing strategies across entire systems, influence build pipelines, and make tooling decisions for engineering teams. The ability to reason about test pyramid allocation per service, contract compatibility, chaos maturity levels, and CI gate design is the core competency of this role. You have built a working model of every one of those dimensions.
Platform Engineer / Developer Experience — Many platform teams are responsible for the internal testing infrastructure: shared Testcontainers configurations, Pact Broker operations, chaos testing libraries, and CI pipeline templates. Engineers who understand both the infrastructure and the testing patterns that run on it are rare and valuable.
The most important thing is to apply this course on a real system before the mental models fade. The techniques only become fluent with repetition on a codebase that matters to you. Pick one service you own, apply the component test pattern this week, add a Pact consumer test next week, and build from there. The full strategy takes months to implement — that is the point. It is a body of work, not a weekend project.
⚠️ Common mistakes
- Treating the capstone as a reading exercise. The gap between reading a component test and writing one from a blank file is larger than it looks. The only way to close it is to open an IDE, add the dependencies, get the context to load, and debug the first stub mismatch. Budget real implementation time — 4–6 hours minimum for the core deliverables.
- Stopping at "tests pass locally." Tests that pass on your laptop but fail in CI reveal environment assumptions. The most common: hardcoded ports (two test classes fighting over 8081), missing Docker socket access, and test ordering dependencies. Run your test suite in a fresh CI environment before marking the capstone complete.
- Skipping the strategy document because it is not code. Engineering managers and architects assess senior engineers partly on their ability to produce written technical reasoning. A well-structured test strategy document — even a one-pager — is a career artefact. Write it, save it, share it. It demonstrates a level of systems thinking that a test class alone cannot show.
🎯 Final practice task
A structured retrospective — 30 minutes.
- Score yourself on the checklist. Count how many items you checked off. Anything under 80% means there are gaps worth filling before moving to the next course.
- Pick one stretch goal. Choose the stretch goal most relevant to your current role or the system you work on. Write down what the first concrete step would be — not "learn K6" but "add a K6 test for the
/ordersPOST endpoint targeting 50 RPS with p99 < 300ms." Schedule 2 hours this week to take that step. - Write a one-paragraph self-assessment. What was the hardest concept in this course? What would you do differently if you were implementing this strategy from scratch on your team? What are you still uncertain about? Writing this down makes the uncertainty concrete and actionable — uncertainty you can name is uncertainty you can address.
- Identify your next course. Based on the "Where to go next" section, pick one course to start next. Commit to a start date.
- Share your work. Post your test strategy document or a key test class in a community, team review, or GitHub repository. Teaching and sharing consolidates understanding faster than any other technique. The engineers who advance fastest in this discipline are the ones who make their work visible.