New · v2 TestingForge v2 is livetwice the functionality at the same subscription price. See what's new →
Deep dive

API testing: things we wish every team did

A blunt, opinionated checklist: contract checks, determinism, environment isolation, secret hygiene, and how to wire API tests into CI without death by red pipelines.

Mar 14, 2026 10 min read TestingForge Team

A blunt list, not a checklist

This is not "10 best practices for API testing in 2026". It is the small list of things we have watched teams skip, and then watched them pay for it on a Sunday at 3 a.m. If you do these, your API suite earns its keep. If you skip them, the suite becomes the thing people mute in CI.

Status codes are the floor, not the ceiling

"200 OK" tells you the server did not crash. It does not tell you the response body matches the contract, the side effects happened, or the new field your mobile client needs is actually present. Assert response shape (schema or fixture), assert side effects (DB row, queued job), and assert error shape for non-2xx — not just the code.

Determinism is a feature, not a nice-to-have

  • Freeze time. Anything that depends on "now" must be controllable.
  • Seed test data per run. Shared mutable fixtures are how you get the famous "passes locally, fails in CI on Tuesdays" bug.
  • Isolate side effects. The test that sends a real email to a real address once is the test that sends 50 000 of them once.

Environment isolation

Run the API in CI against an ephemeral database, not against staging. Staging is shared, slow, and somebody else's test will eat your fixture. If you cannot run the API locally, your API tests are not really tests — they are integration probes against a moving target.

Secrets and auth

Do not bake real tokens into the suite. Use a test-only auth flow, expire tokens fast, and assume the suite repo will leak some day. Test the unhappy auth paths — expired token, wrong scope, revoked key. They are where production incidents actually live.

Wire it into CI without making the team hate the pipeline

  • Run on every PR, not nightly. Nightly = "we'll find out tomorrow" = "we won't find out".
  • Split fast and slow suites. The fast suite is a gate. The slow suite is a signal.
  • Make a failure tell the engineer which contract broke and which commit changed it. Generic red checkmarks get muted.

Stop testing things that don't matter

Coverage is a vanity metric. 200 tests for one CRUD endpoint and zero tests for the payment webhook is a worse suite than 50 tests on the things that would page someone at night. Once a quarter, delete the tests that have not failed in a year and that no one would notice if they were gone.