Q&A
What is API testing in software testing?
Overview
APIs are the contracts between software components (client↔server, service↔service). API testing exercises those contracts directly - without a browser or UI - by issuing requests and validating responses. Because it skips the fragile UI layer and targets logic directly, it's a cornerstone of modern test strategy and integrates well into CI/CD.
graph TD
A[API Testing] --> B[Send request to endpoint]
B --> C[Validate response]
C --> C1[Status code]
C --> C2[Body / schema]
C --> C3[Headers]
C --> C4[Response time]
A --> D[Types: functional, integration, performance, security]
style A fill:#1e1b4b,color:#fff
What It Validates
- Status codes - correct codes for success/error (200, 201, 400, 401, 404, 500).
- Response body - correct data, structure, and types (often validated against a schema).
- Headers - content type, caching, auth-related headers.
- Error handling - sensible responses to bad input, missing auth, edge cases.
- Performance - response time under expected load.
- Security - authentication, authorization, input validation, no data leakage.
Where It Sits in the Test Pyramid
The "test pyramid" recommends many fast unit tests, a moderate number of integration/API tests, and few slow UI/E2E tests. API tests are the valuable middle layer: broader than unit tests (they exercise real request handling, routing, serialization, often the DB) yet far faster and more stable than UI tests. A bug in business logic surfaces here without UI flakiness.
Types of API Testing
| Type | Focus |
|---|---|
| Functional | Does each endpoint return correct results? |
| Integration | Do services/components work together via their APIs? |
| Contract | Does the API match its agreed schema/contract (e.g. consumer-driven)? |
| Load/Performance | Behavior under high request volume |
| Security | Auth, injection, rate limiting, data exposure |
Example (Python, pytest + requests)
import requests
BASE = "https://api.example.com"
def test_get_user_returns_200_and_correct_shape():
res = requests.get(f"{BASE}/users/1")
assert res.status_code == 200
body = res.json()
assert body["id"] == 1
assert "email" in body
def test_create_user_requires_auth():
res = requests.post(f"{BASE}/users", json={"name": "Ada"})
assert res.status_code == 401 # unauthorized without a token
def test_invalid_input_returns_400():
res = requests.post(f"{BASE}/users",
json={}, headers={"Authorization": "Bearer t"})
assert res.status_code == 400
Example (JavaScript, Supertest)
const request = require("supertest");
const app = require("../app");
test("GET /users/1 returns the user", async () => {
const res = await request(app).get("/users/1");
expect(res.status).toBe(200);
expect(res.body).toHaveProperty("email");
});
Common Tools
- Postman / Newman - manual + automated collections, great for exploration and CI.
- REST Assured (Java), requests/pytest (Python), Supertest (Node).
- Schema/contract tools - JSON Schema validation, Pact (consumer-driven contracts), OpenAPI-based validation.
- Load - k6, JMeter, Gatling.
Why This Matters in Interviews
QA/backend interviews use this to assess testing strategy. Cover: what API tests validate (status codes, body/schema, headers, timing, errors, security), why they're valuable (faster and more stable than UI tests, target business logic directly - the middle of the test pyramid), the types (functional, integration, contract, load, security), and tooling. Mentioning schema/contract testing and CI integration signals a mature testing mindset.
Common Pitfalls
- Only testing the happy path; neglecting error codes, auth failures, and edge cases.
- Asserting only the status code, not the response body/schema.
- Flaky tests due to shared mutable state or real external dependencies (use test data/mocks).
- Skipping security checks (auth, authorization boundaries, input validation).
- Over-relying on UI/E2E tests for logic that API tests could cover faster.
References
- Postman API testing: https://learning.postman.com/docs/writing-scripts/test-scripts/
- Martin Fowler, "The Practical Test Pyramid": https://martinfowler.com/articles/practical-test-pyramid.html