API testing fundamentals
An API test sends a request and checks the response against what you expected. Everything else in testing is a variation on that sentence. This page covers what to check, the kinds of test, and how to choose where to begin.
The shape of every test
- Arrange: get the system into a known state, and prepare the input.
- Act: send one request.
- Assert: check the response.
In ApiWorkbench the request is the act, the Tests tab holds the asserts, and earlier requests in the collection (a sign-in, a create) are the arrange.
A test must be able to fail. A request with no checks proves only that the server answered. Before trusting a new test, break something and confirm the test notices.
Five things to check in a response
Most weak test suites check only the first.
| Check | Question | In ApiWorkbench |
|---|---|---|
| Status | Is it the right code, not merely a 2xx? | Status equals 201 |
| Body content | Are the important values correct? | JSON field equals, Body contains |
| Body shape | Are the fields present, with the right types? | JSON field equals per field, or a schema check in a script |
| Headers | Is the content type right? Is Location or a cache header present? | Header contains |
| Time | Did it answer fast enough? | Time below (ms) |
A sixth applies to requests that change something: the effect. After a POST creates an order, a follow-up GET should find it. That needs two requests and a capture.
Kinds of API test
| Kind | Sends | Checks |
|---|---|---|
| Smoke | The simplest request to each main endpoint | The service is alive at all |
| Functional | Valid requests | Each endpoint does what it should |
| Negative | Invalid requests on purpose | Errors are correct and helpful |
| Boundary | Values at the edges of the rules | The limits are where they should be |
| Security | Requests without, or with the wrong, credentials | Nothing leaks, nothing is open |
| Workflow | A sequence of dependent requests | A real journey works end to end |
| Contract | Anything | The response still has the agreed shape |
| Performance and load | Many requests | Speed and error rate under pressure |
| Resilience | Requests to a failing dependency | The client copes |
| Regression | All of the above, again | Nothing that worked has broken |
Each has its own guide, listed on the testing guides page.
What to test first
You cannot test everything. Rank by two questions: how likely is it to break, and how much does it hurt if it does?
- The paths that earn the money. Sign-in, checkout, whatever the product exists for.
- Anything that writes. Creating, changing and deleting do more damage when wrong than reading.
- Anything behind a lock. Authentication and permission errors are the expensive kind.
- Whatever changed recently. New code is where new bugs live.
- Whatever broke before. A bug that happened once gets a test so it cannot return unnoticed.
Properties of a good test
- One reason to fail. A test that checks ten things tells you little when it goes red. Small tests point at the problem.
- Independent. It should not need another test to have run, unless the dependence is the point, as in a workflow. Each workflow creates its own data.
- Repeatable. Same result every time, on any machine. Avoid depending on today's date, a record someone might delete, or the order of an unsorted list.
- Readable. The request name says what is being tested:
Create order without a token, notTest 7. - Fast. Slow suites do not get run.
The test environment
- Never test against production data you care about. Use a test environment, a test account, or a mock.
- Keep the address in a variable. With
{{baseUrl}}in every request, switching from the mock to staging is one change. See Variables and environments. - Keep secrets in environments, marked secret, not written into requests.
- Use a mock when the real thing is unavailable, unstable or cannot be made to fail on demand. See Testing with mocks.
A first suite, in order
For a new API, build up like this:
- One smoke request per main endpoint, each with a status test.
- Add content and time checks to those.
- Add the negative twin of each: missing field, wrong id, no token.
- Chain the main journey with captures.
- Put the address and credentials in an environment.
- Run the collection with the runner. When it is green, you have a regression suite.
The Todo API lab is this list, already built.
Check yourself
Question 1 of 6
In the arrange, act, assert shape, which part is the request itself?