API Testing for Senior Testers
Every modern NZ application has an API behind it. Senior testers who can verify endpoints directly — without the UI as an intermediary — find bugs faster, test more thoroughly, and are far more valuable to their teams.
1 The Hook
A Wellington fintech submits an NZTA vehicle lookup API call. The UI displays "Vehicle not found" in clean, formatted text. Looks fine. The tester marks it pass and moves on.
Except the API is returning a 500 with a stack trace in the response body. The stack trace contains the database connection string — including credentials. The UI is swallowing the error entirely, formatting the failure as a presentable "not found" message. Manual testers who only test through the UI miss this completely. A senior tester who runs Postman against the endpoint catches it in five minutes.
That stack trace also reveals the connection string is pointing to the production database from what is supposed to be the test environment. The team has been running load tests against production data for three weeks. If that response had ever been logged by a client or cached in a proxy, the credentials would be exposed. One Postman request would have surfaced this. No one made it.
2 The Rule
Test the API layer independently of the UI. The UI is a presentation filter — it hides errors, formats data, and makes broken things look fine. The API tells the truth.
3 The Analogy
The UI is front of house. The API is the kitchen.
A restaurant's dining room is designed to be presentable. The kitchen is where the actual work happens, and where you can see what's really going on. A guest at a table can't see a cockroach in the kitchen. A council health inspector walking in through the back door will find it in five minutes. When you test only through the UI, you're the guest. When you test the API directly, you're the inspector.
4 Watch Me Do It
Testing an MBIE Business Registry endpoint in Postman. The endpoint returns company details by NZBN.
Step 1: Set up the GET request. URL: https://api.business.govt.nz/sandbox/nzbn/v5/entities/9429000000001. Add an Authorization: Bearer <token> header. Click Send.
Step 2: Read the response. Check status code (200 = found, 404 = not found, 401 = auth failure, 500 = server error). Check response time — over 2 seconds on a lookup endpoint is worth flagging. Check the response body is valid JSON, not an HTML error page.
Step 3: Add assertions in the Tests tab.
// In Postman Tests tab
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response time under 500ms", function () {
pm.expect(pm.response.responseTime).to.be.below(500);
});
pm.test("Company name is present", function () {
const body = pm.response.json();
pm.expect(body.entityName).to.be.a('string').and.not.empty;
});
pm.test("GST number format is valid", function () {
const body = pm.response.json();
pm.expect(body.gstNumber).to.match(/^\d{8,9}$/);
});Step 4: Test the error path. Submit a POST with a missing required field. Expect 400 (Bad Request) or 422 (Unprocessable Entity). If the API returns 200 with an error body, that's a contract defect worth raising. The response body must also not contain a stack trace, internal paths, or database names.
5 When to Use It
Use API testing when: validating business logic that the UI doesn't expose; testing error handling and edge cases; checking auth and authorisation flows; verifying a new endpoint before the UI is built; measuring response time on a single endpoint; testing what happens with malformed or missing input.
Don't replace UI tests. API tests verify the contract — what data is exchanged and whether it's correct. UI tests verify the experience — whether users can actually complete tasks. Both are needed. API tests are faster and more specific. UI tests catch integration problems between the API and the front end.
Triggers to reach for Postman: a bug was reported but the UI looks fine; you're testing a new endpoint with no front end yet; the developer says "the API is correct, must be the UI"; you need to test 50 combinations of input that would take an hour via the UI.
6 Common Mistakes
🚫 Trusting the UI as proof the API is correct
I used to think: if the UI shows the right data, the API is fine.
Actually: the UI might be caching stale data, suppressing errors, or formatting incorrect values so they look right. Always verify the API response directly. The UI is a filter, not a source of truth.
🚫 Treating 200 OK as proof of success
I used to think: 200 OK means the request succeeded.
Actually: some APIs return 200 with {"success": false, "error": "..."} in the body. Always assert on the response body content, not just the status code.
🚫 Waiting until you know all HTTP verbs before starting
I used to think: I need to understand GET, POST, PUT, PATCH, DELETE, and OPTIONS before I can test an API.
Actually: GET and POST cover 80% of business flows. Start there. You'll learn the rest in context.
🚫 Leaving auth testing to the developer
I used to think: auth is the developer's responsibility.
Actually: missing auth headers, expired tokens, and wrong OAuth scope are among the most common API defects in production. Test every auth scenario: no token, expired token, wrong scope, another user's token.
7 Now You Try
You're testing the IRD's KiwiSaver contribution API. A POST request submits: employee IRD number, employer IRD number, contribution period (YYYYMM), and contribution amount. Write 5 test cases covering: success, missing fields, invalid IRD number format, incorrect period format, and a boundary condition for contribution amount. Ask the AI to review your test cases and identify any gaps.
8 Self-Check
Click each question to reveal the answer.
Q1. What's the difference between a 401 and a 403 response?
401 Unauthorised means the request has no valid credentials — the client isn't authenticated at all (missing or expired token). 403 Forbidden means the credentials are valid but the user doesn't have permission to access that resource. A logged-in user getting a 403 on another user's record is expected behaviour. Getting a 403 on their own record is a bug.
Q2. What does it mean when an API returns 200 but the test still fails?
The status code only tells you the HTTP layer succeeded. The response body may contain an application-level error: {"success": false, "error": "Account not found"}. Your test should assert on specific fields in the body — not just the status code. Always read the full response, not just the headline.
Q3. Why test the API separately from the UI when both use the same back end?
Because the UI filters and transforms what the API returns. Error messages get formatted into friendly text. Invalid data gets caught by client-side validation before it reaches the API. Caches serve stale responses. Testing the API directly removes all those layers and shows you exactly what the server is doing — including things the UI would hide.
Q4. What is idempotency and why does it matter for PUT requests?
An idempotent operation produces the same result whether you run it once or ten times. PUT should be idempotent — sending the same PUT request twice should not create two records or change the outcome. If a PUT creates a duplicate on retry (after a network failure), that's a defect. This is critical for payment and financial APIs where retries are common.
9 ISTQB Mapping
CTAL-TA v3.1.2 — Section 3.2.4: Testing web services — directly covers API testing scope, tools, and test design at integration level.
CTAL-TA v3.1.2 — Section 3.2.5: Testing REST APIs — status codes, request/response validation, JSON Schema, and auth verification.
CTFL v4.0 — Section 4.1: Test analysis — deriving API test conditions from acceptance criteria and API contracts. Applicable when turning an OpenAPI spec into a test plan.