The API Testing Guide: Types, Tools, and How to Start
Quick answer: API testing is how you verify that a service honors its contract and supports real business flows, not just that a happy-path request returns 200. Layer it: request validation and unit checks at the bottom, contract tests that catch drift between producer and consumer, and end-to-end scenario tests that walk a user journey across several operations. The tests that matter most are the ones that fail when the contract breaks — ordering, timing, and restart behavior — and they have to run in CI, because a green run on the developer's machine is not evidence.
This guide organizes the test types, the tools, and the traps — including a long list of ways AI-generated tests can look green while verifying nothing. Follow the links for the concrete examples.
The layers of API testing
Start from the contract and move outward. At the lowest level, validate that requests and responses match the schema; then verify that two services agree on the contract between them; finally, walk complete business scenarios. You do not need a heavyweight broker to do contract work — API contract testing without Pact shows a lighter approach. For the outer layer, scenario testing for user journeys chains operations together, and the mindset shift is in a 200 is not done: run the business scenario.
Catching breaking changes before release
The highest-leverage test in an API pipeline is a diff that flags breaking changes — removed fields, changed types, tightened constraints. Set it up in CI with detecting breaking API changes with OpenAPI diff. This catches the class of bug where a producer bumps a version and assumes consumers will keep up; an agent bumped a major version while CI stayed green is exactly what happens without it.
Testing streaming and async APIs
HTTP request/response is the easy case. Streaming and bidirectional protocols need different assertions: you verify sequences of events, backpressure, and reconnection rather than a single response. The patterns are in how to test SSE (Server-Sent Events) and how to test WebSocket APIs. Long-running jobs return before the result is ready; testing them means polling status and handling timeouts, covered in async jobs with 202 and Location.
What to assert: stop testing the perfect request
Tests that only send a well-formed request and assert 200 prove almost nothing. The real failures live in malformed input, missing permissions, and partial failure. The argument is in stop testing the API with the perfect request. When a response is technically valid but semantically wrong — valid JSON but the wrong content type — see valid JSON, wrong content type (415), and make sure you assert against the documented error shape in RFC 9457 error responses.
How AI-generated tests fake coverage
AI is very good at producing tests that compile and pass, and very good at passing for the wrong reasons. Before you trust an AI-written suite, check each of these documented failures:
- Tests pass against the wrong contract
- The test mirrors the code instead of asserting behavior
- Tests that pass but don't verify
- Hardcoding today's date so the test expires
Agent test anti-patterns
Autonomous agents repeat a recognizable set of mistakes when asked to make tests pass. Each one is a real case worth scanning for in review:
- Mocking the very function under test (and the same mistake written out)
- Testing the case the agent invented instead of the bug
- Relaxing the assertion to go green
- Deleting the failing test
- Weakening assertions to fix a flaky test
- Patching flakiness with a sleep
- Green only under a fixed execution order
Tests only count if they run in CI
Local green is not verification. The environment, data, and ordering differ from CI, and the bugs that only appear there are the ones that reach production. Read local green, CI red, passes unit tests but never runs the app, and green CI after an AI refactor means nothing — the last one explains why a green build can coexist with a broken contract. Slow tests are also telling you something; the slow ones often tell the truth. A test that outlives the implementation it was written for is a good test; a test that survives its own implementation explains the distinction.
Testing MCP servers and agent tools
When the API is exposed to AI agents through MCP, testing moves up a level: you verify that tools are listed, accept the documented inputs, and return results an agent can act on. The procedure is in how to test and debug an MCP server, and versioning tools without breaking consumers is in versioning MCP tools without breaking agents.
Where to go next
Testing pairs naturally with the other lifecycle guides. When a dependency is not ready, use API mocking; when a test fails, follow the API debugging guide; and to keep agents on the contract, read the AI coding agent guide.
FAQ
What percentage of API testing should be contract vs end-to-end? There is no fixed ratio, but the healthy shape is a broad base of fast schema/contract tests and a small number of slow scenario tests covering the critical journeys. End-to-end tests are expensive and flaky; keep them for flows that genuinely cross services.
How do I test an API I don't control? Treat it as a contract you consume: record the responses you depend on, pin to them with contract tests, and add a canary that warns when the third party changes. Mocking keeps your suite independent of their uptime.
Are AI-written tests safe to merge? Only after a human reads the assertions and confirms the test would fail if the behavior broke. A test that cannot fail is a cost, not coverage.