‹ All posts

API tests that don’t break when the API changes

One test class per API breaks every time a field is renamed. Describe each test as data instead, and a rename becomes a one-line config change.

Test automationRest-AssuredAPIs

The problem#

A class per integration is easy to read at ten tests. At 190, a renamed field means editing many files — and only the person who wrote the framework can add a test.

Tests as data#

json
{
  "journey": "claim-settlement",
  "steps": [
    {
      "name": "register claim",
      "method": "POST",
      "path": "/claims",
      "extract": { "claimId": "$.result.claimSeqID" },
      "expect": { "status": 201 }
    },
    {
      "name": "settle",
      "method": "POST",
      "path": "/claims/${claimId}/settlement",
      "expect": { "status": 200, "body": { "$.status": "APPROVED" } }
    }
  ]
}

One engine reads this: fill in the values, send, check, extract, move on. Once it can do those five things it hardly changes again. New tests are config — and someone who never opens Java can review them.

Stop on a missing value#

If a step needs claimId and nothing extracted it, stop right there and name it. Sending “null” instead gives you a confusing 400 two steps later, and someone loses an afternoon.

Separate values for parallel runs#

Give every journey its own store of extracted values. With one shared store, parallel journeys overwrite each other and a different test fails each run.

Check in layers#

LayerChecksFails when
TransportStatus code and response timeThe service is down or slow
SchemaResponse matches the JSON SchemaThe contract changed
BusinessValues are right for this inputThe logic changed
Next stepValues the next call needs are presentThe chain will break

Separate layers make failures easy to read. “Schema failed, business passed” means a field moved. “Schema passed, business failed” means the logic changed.

Test data#

  • Create what the test needs in setup, and delete it afterwards.
  • Never hard-code an ID a person might edit in a shared environment.
  • When creating data is slow, borrow it from a pool and give it back.

Catch breaking changes before they deploy#

If both environments publish an OpenAPI spec, compare them in the pipeline. Fail on removed fields, changed types and new required fields — before a client finds them.