You now know what's possible: functional tests, contract tests, schema validation, performance assertions, security checks, GraphQL specifics, the whole map. The hard question is which of those to actually do, and when. A good API testing strategy answers five questions: what to test, how much, with what tools, when in the pipeline, and who's responsible. This lesson is about turning the techniques you've learned into a coherent plan that works for a real team — not the textbook ideal, but the realistic version that ships and stays useful.
The five questions
A complete strategy answers, in order:
- What to test — which endpoints, which behaviours, which risks.
- How much — depth (per-endpoint coverage) vs breadth (number of endpoints).
- What tools — manual exploration, automation framework, performance harness, CI integration.
- When — which suites run on every PR, which on every deploy, which nightly, which pre-release.
- Who — developers, QA, SDETs, product engineers. Who writes which tests, who maintains them.
Skip any of the five and the strategy gets fuzzy. "We test everything" without a what becomes shallow coverage; "use Postman" without a who becomes one tester's hobby; "every PR runs all tests" without a how much becomes 90-minute CI.
A layered suite
The most common practical shape is a stack of suites, each with a different purpose, frequency, and runtime budget:
Read top to bottom — fast, narrow checks at the top; slow, broad checks at the bottom. Each layer adds confidence; each layer is run at the frequency justified by the cost.
Smoke tests
The shortest possible "is the system alive?" check. Hits the health endpoint, the login flow, and the most critical read path. Goal: under one minute, run after every deploy, fail loudly. If smoke fails, roll back and skip everything else.
Functional tests
The bulk of API coverage. CRUD on each endpoint, validation, auth, key error paths. Run on every PR. Aim for 5-10 minutes total — beyond that, developers stop running them locally.
Contract tests
Per-service, run on PRs that change either consumer or provider. Verifies that pairwise integrations still hold. Cheap (each side runs independently) and high-value in microservice setups.
Integration tests
End-to-end across multiple services. Verifies that flows work — order created, payment processed, email sent, audit logged. Run nightly, not on every PR (too slow, too dependent on shared resources).
Performance tests
Load, stress, soak. Run weekly or before major releases. Lives in a dedicated environment so it doesn't affect functional CI.
Risk-based prioritisation
Within each layer, depth depends on risk. A discount engine on the checkout path deserves dozens of negative-case tests; an "about us" content endpoint needs one read test.
Rough heuristic: weight test investment by (probability of breaking) × (cost when it breaks).
- High × high — payments, auth, data persistence on critical objects. Deep coverage, contract tests, performance tests.
- High × low — frequently-changing UI-helper endpoints. Functional tests, schema checks. Skip perf.
- Low × high — rarely-changed but critical (e.g. password reset). Functional + contract, audited quarterly.
- Low × low — stable, low-stakes endpoints. Smoke + schema validation only.
A useful exercise: list every endpoint, score it on both axes, sort. The top decile gets the deep treatment; the bottom decile gets minimal coverage.
Tool selection
Three categories, one tool each (more becomes operational debt):
- Exploration — Postman, Insomnia, or Bruno. For poking at endpoints, sharing requests with colleagues, building first drafts of tests.
- Automation — language-native HTTP libraries (
requests,axios, RestAssured, the testing course you've already taken). Code-based tests version-control and CI well; GUI-only tests tend to atrophy. - Performance — k6, Gatling, JMeter, or Locust. Run from a dedicated environment; never against production unless explicitly load-tested.
Avoid mixing automation tools across the team — pick one, document it, train new joiners on it. Two tools means two sets of helpers, two CI integrations, two debugging skills to maintain.
Test environments
The decision matrix:
- Local — for developer-run smoke and functional tests. Fastest feedback. May not match prod data shape.
- CI ephemeral — spun up per PR. Reproducible, isolated, but expensive in build minutes.
- Shared staging — closest to prod, but contention with other teams. Best for nightly integration runs.
- Dedicated test environment — your team's sandbox. Worth investing in once you have flaky shared-staging issues.
- Production — only for read-only smoke checks on truly critical paths. Never write tests, never destructive ones.
Most teams settle on local + ephemeral CI for fast feedback, plus shared staging for nightly broad runs.
Who owns tests
Three roles, three responsibilities, one collaboration model:
- Developers — write unit tests for their code, write functional tests for endpoints they own. Tests ship in the same PR as code.
- QA / SDET — own the test framework, write cross-cutting tests (auth matrix, contract verification, performance), audit coverage gaps, mentor developers on test design.
- Platform / SRE — own the smoke tests that gate production deploys. Often tiny in count, large in importance.
Anti-patterns to avoid:
- "QA writes all the tests, devs ship code" — tests lag, devs don't think about testability, QA becomes a bottleneck.
- "Devs write all the tests, QA does manual" — coverage gaps in cross-cutting concerns, manual testing doesn't scale.
The healthy model is shared ownership with QA as the centre of expertise, not the sole producer.
When the strategy changes
A strategy isn't carved in stone. Trigger reviews when:
- You release a major new product area — new endpoints, new contracts, new performance budgets.
- A class of bug keeps shipping despite tests — gap in the strategy worth filling.
- Test runtime grows past the team's tolerance — time to parallelise, tier, or remove dead tests.
- A new tool genuinely improves something — integrate cautiously, retire what it replaces.
- Headcount or roles shift — who owns what may need to be revisited.
Review every 6-12 months at minimum, even if nothing visibly broke.
A starter strategy for a new project
If you're standing one up from scratch, here's a minimum viable shape:
- One Postman collection for exploration. Shared with the team.
- Functional tests in code — one assertion per endpoint, schema validation, auth coverage. Run on every PR.
- Smoke tests — three to five tests that prove the system is alive. Run post-deploy.
- CI integration — GitHub Actions / Jenkins / GitLab pipeline that runs functional + smoke.
- One nightly broader run — full functional suite plus any integration tests that exist.
- A 30-minute monthly review — what failed, what flaked, what's missing.
Iterate from there. Add contract testing when you have multiple services, performance testing when latency matters, security testing when scope demands it.
⚠️ Common mistakes
- Optimising for coverage percentage. "We have 80% coverage" can mean anything. Optimise for which endpoints have which kinds of tests at the depth their risk justifies.
- Letting CI run grow unchecked. Ten minutes is the developer attention budget; beyond that, people start skipping local runs. Tier and trim.
- Testing what's easy to test. It's tempting to write deep coverage on simple GETs and skim the complex flows. Resist — the bugs hide in the complex flows.
🎯 Practice task
Sketch a strategy for your team. 30-40 minutes — no code.
- List your team's product areas. Pick one, the most critical.
- Enumerate the endpoints in that area. Score each on probability-of-breaking (1-3) and cost-when-broken (1-3).
- Define what each layer (smoke, functional, contract, integration, performance) means concretely for this area. Which endpoints belong in which layer?
- Sketch a CI pipeline: what runs on PR, what runs on deploy, what runs nightly.
- Identify the biggest gap — a layer or a class of test you don't currently have. Estimate the effort to add it.
- Write your strategy down in a single page. Share with one engineer and one product person. Note their reactions — those are your strategy's blind spots.
You can now think about API testing as a system. The next lesson tackles the engineering substrate that determines whether the system actually works in practice: test data.