All posts
api-testingautomationci-cd

API testing 101: the contract-first approach for modern teams

Most teams test their APIs by clicking buttons in a UI. There's a better way that costs almost nothing to set up.

Linda SarpongMay 29, 202610 min read
API testing 101: the contract-first approach for modern teams

If you're testing your API by clicking buttons in your frontend and watching the network tab, you're doing it the hard way. You're also coupling your API correctness to your UI correctness, which means a frontend regression silently masks an API regression.

The fix is contract-first API testing, and it's both faster and cheaper than what you're probably doing today.

A computer screen showing API test results in a CI pipeline

The basic idea, in one paragraph

For each public-ish endpoint, write a small set of tests that:

  1. Make the request directly to the API (not through the UI).
  2. Assert against the response shape and a few key values.
  3. Run on every PR, in CI, in seconds.

That's it. No UI, no browsers, no flaky end-to-end runs.

What "contract-first" means in practice

A contract test is a small, deterministic check that says "this endpoint, given this input, returns this shape". It doesn't test the entire surface of the API — it locks down the part your consumers depend on.

- name: Returns 200 + the new bug
  method: POST
  url: /api/v1/bugs
  body:
    title: "Test bug from CI"
    severity: "high"
  assertions:
    - status == 201
    - body.title == "Test bug from CI"
    - body.id matches uuid
    - duration_ms < 500

A contract test is not:

  • A unit test (those live in your codebase, not a separate tool).
  • A load test (those need different infrastructure).
  • A test of "all the business rules" (those should live close to the code that implements them).

It's a behavioral promise to the outside world, locked down.

A diagram showing API contracts between services

The four kinds of contract assertions worth writing

For every endpoint you care about, write all four:

  1. Status + shape. "200 OK, response has these fields."
  2. One happy-path value check. "Created bug's title matches what I sent."
  3. One auth/permissions check. "Without my token, I get 401."
  4. One performance budget. "p95 < 500ms on this endpoint."

That's typically 4 × N assertions where N is the number of endpoints you actually care about — usually under 30 for most teams.

How Lepta QA does this

In Lepta QA, an API test is a declarative spec — request, assertions, optional setup steps. You write it once, save it as a test case, and it runs:

  • On every push, in CI.
  • On a schedule against staging and production.
  • Every time someone changes the underlying schema (we hook into your OpenAPI spec).

When something fails, you get the full request, response, headers, timing, and a diff against the last green run. No "I'll just curl it locally to see what's wrong" — the run report has everything.

The trick that gets your team to actually write them

Don't write them upfront. Write them after a bug ships in production.

Every API-side bug you fix gets a contract test that would have caught it. Six months later, you have a meaningful suite. Two years later, you have a regression net that catches breaking changes before they ship.

The cheapest contract test is the one you write the day after a bug bites you. Don't try to predict; just don't repeat.

What to skip

You can confidently not write contract tests for:

  • Internal-only endpoints with one consumer (test those at the consumer).
  • Admin-only debug routes.
  • Endpoints whose only consumer is your own backend.

Focus on the surface that other systems — your frontend, your mobile app, your customers' integrations — actually depend on. That's where breaks cost real money.

Try Lepta QA

Stop juggling tabs. Ship with confidence.

Run live testing rooms, capture bugs, and let AI summarize the work — all in one workspace.