1. Why API Testing? The Modern Test Automation Pyramid
In traditional QA teams, testing was treated as an inverted pyramid (the "ice cream cone" anti-pattern): 80% of test effort was spent creating slow, brittle UI tests in Selenium, while the backend API layer was ignored. When a button click failed, QA spent hours triaging whether the bug was a CSS locator break, a network timeout, or an actual backend calculation defect.
The Ideal Engineering Test Pyramid
UI Tests (10% of Suite) — End-to-End User Journeys
Only test critical user journeys (signup, complete checkout, fund transfer). Slower execution (3-8 seconds per test). High maintenance costs.
API / Integration Tests (30-40% of Suite) — The SDET Sweet Spot
Tests business logic, validations, authentication, database persistence, and external service contracts. Executes in milliseconds (50-200ms per call). Zero UI flakiness.
Unit Tests (50-60% of Suite) — Pure Code Functions
Written by developers in JUnit/Jest. Verifies isolated classes and algorithmic edge cases in microseconds.
2. Anatomy of an HTTP Request & Response
REST (Representational State Transfer) is built on the stateless HTTP/1.1 and HTTP/2 protocols. To write reliable API automation, you must master the structural components of every request and response:
Request Anatomy
- Method: GET, POST, PUT, PATCH, DELETE
- Base URI & Path:
https://api.testerrank.com/v1/accounts - Query Parameters: Filter & sort:
?status=active&limit=20 - Headers: Metadata like
Content-Type: application/jsonandAuthorization: Bearer <token> - Body: Payload payload for POST/PUT/PATCH (JSON)
Response Anatomy
- Status Code: 200 OK, 201 Created, 401 Unauthorized
- Response Headers: Server metadata (
Date,Content-Length,X-Request-ID) - Response Body: Serialized JSON object or array representing system state
- Response Latency: Time in milliseconds to complete round-trip (target < 300ms)
3. HTTP Methods & Idempotency Deep Dive
An HTTP method is idempotent if making the identical request N times produces the exact same server side-effect as making it once. Understanding idempotency is essential for designing resilient automated test retries:
| Method | Safe? | Idempotent? | Purpose | Expected Status Code |
|---|---|---|---|---|
| GET | Yes | Yes | Retrieve representation of a resource without mutation | 200 OK |
| POST | No | No | Create new subordinate entity. Repeating creates duplicates | 201 Created |
| PUT | No | Yes | Complete replacement of existing resource at known URI | 200 OK / 204 No Content |
| PATCH | No | Generally No | Partial mutation of specific fields without replacing whole payload | 200 OK |
| DELETE | No | Yes | Delete resource at URI. Subsequent calls return 404 or 204 | 204 No Content / 200 OK |
4. HTTP Status Code Taxonomy
Never accept APIs that return 200 OK with an internal error object inside the JSON body (e.g., { "status": "error" }). This violates the HTTP specification. Ensure endpoints return accurate RFC status codes:
2xx Success
- 200 OK: Request succeeded with payload.
- 201 Created: Resource created (accompanies Location header).
- 202 Accepted: Request accepted for asynchronous background queue processing.
- 204 No Content: Succeeded, intentionally no response body (e.g., DELETE).
4xx Client Errors
- 400 Bad Request: Malformed JSON or invalid schema format.
- 401 Unauthorized: Unauthenticated — missing, expired, or invalid token.
- 403 Forbidden: Authenticated, but user role lacks authorization.
- 404 Not Found: Resource URI does not exist in database.
- 409 Conflict: State conflict (e.g., duplicate email address).
- 422 Unprocessable: Valid JSON syntax, but violates business rule.
5. Authentication Mechanisms & BOLA / IDOR Testing
Modern microservices use JSON Web Tokens (JWT) for stateless authorization. A JWT contains three Base64URL-encoded segments separated by periods: header.payload.signature.
Testing for Broken Object Level Authorization (BOLA / IDOR)
BOLA occurs when an API accepts an object identifier (like an account ID or order ID) from a client request, but fails to verify that the requesting user owns that object.
// Step 1: Authenticate as User A (Attacker) and get token
String tokenUserA = authClient.login("attacker@test.com", "Password123!");
// Step 2: Attempt to read User B's private bank account using User A's token
given()
.header("Authorization", "Bearer " + tokenUserA)
.when()
.get("/api/v1/banking/accounts/ACC-VICTIM-9988")
.then()
// Must return 403 Forbidden or 404 Not Found — NEVER 200 OK!
.statusCode(anyOf(is(403), is(404)));6. Postman Collections & Chai Assertions Masterclass
Postman is the industry standard for API exploration and smoke testing. Instead of manual verification, write automated Chai.js test assertions in the Tests tab of your requests:
// 1. Assert HTTP Status Code
pm.test("Status code is 201 Created", function () {
pm.response.to.have.status(201);
});
// 2. Assert Response Time SLA (< 400ms)
pm.test("Response time is under 400ms", function () {
pm.expect(pm.response.responseTime).to.be.below(400);
});
// 3. Extract and assert JSON body fields
const response = pm.response.json();
pm.test("Account created with correct initial balance", function () {
pm.expect(response).to.have.property("accountId");
pm.expect(response.status).to.eql("ACTIVE");
pm.expect(response.balance).to.be.at.least(0);
});
// 4. Save extracted ID into Environment Variable for downstream calls
pm.environment.set("currentAccountId", response.accountId);7. Enterprise Java REST Assured Automation Framework
For enterprise CI/CD automation, Java SDETs write test suites using REST Assured. It employs a fluent BDD syntax: given() (prerequisites, headers, body) → when() (HTTP action) → then() (validations).
package com.testerrank.api.tests;
import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;
public class BankingApiTest {
private RequestSpecification requestSpec;
@BeforeClass
public void setupSpecification() {
requestSpec = new RequestSpecBuilder()
.setBaseUri("https://www.testerrank.com")
.setBasePath("/api")
.setContentType(ContentType.JSON)
.addHeader("Accept", "application/json")
.build();
}
@Test(description = "Verify fund transfer API validates account balances")
public void testFundTransferValidation() {
String transferPayload = """
{
"fromAccount": "ACC-10029",
"toAccount": "ACC-99482",
"amount": 250.00,
"currency": "USD"
}
""";
given()
.spec(requestSpec)
.header("Authorization", "Bearer mock_jwt_token_sample_2026")
.body(transferPayload)
.when()
.post("/practice/banking/transfers")
.then()
.statusCode(200)
.body("status", equalTo("COMPLETED"))
.body("referenceNumber", notNullValue())
.body("remainingBalance", greaterThanOrEqualTo(0.0f))
.time(lessThan(1000L)); // Assert response latency within 1000ms
}
}8. JSON Schema Validation & Contract Testing
Asserting individual JSON fields (like .body("status", equalTo("ACTIVE"))) verifies data correctness, but it does not protect against missing fields or type mutations. JSON Schema Validation validates the entire contract against a defined schema specification:
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
@Test(description = "Verify customer account payload adheres to JSON Schema Draft-07")
public void verifyAccountContractSchema() {
given()
.spec(requestSpec)
.when()
.get("/practice/banking/accounts/ACC-10029")
.then()
.statusCode(200)
// Validates entire response payload matches src/test/resources/schemas/account-schema.json
.body(matchesJsonSchemaInClasspath("schemas/account-schema.json"));
}9. The Negative Testing & Boundary Analysis Matrix
Amateur testers only test the happy path. Staff SDETs design comprehensive negative test matrices to ensure the server fails securely and gracefully:
| Test Scenario | Input Payload / Condition | Expected Status | Validation Check |
|---|---|---|---|
| Negative Amount Transfer | amount: -500.00 | 422 Unprocessable | Error message specifies amount must be > 0 |
| Zero Amount Transfer | amount: 0.00 | 422 Unprocessable | Boundary check prevents empty debit transactions |
| Missing Required Fields | omitted "toAccount" key | 400 Bad Request | Schema validation failure returned to client |
| Expired Bearer Token | exp claim in past | 401 Unauthorized | Authentication gateway rejects request before business logic |
| SQL Injection Probe | "' OR 1=1 --" | 400 Bad Request | Parameterized query prevents database syntax error |
10. Running Postman Suites in CI/CD with Newman
Newman is the headless CLI runner for Postman. It allows you to run Postman collections in Jenkins, GitHub Actions, or GitLab pipelines without a desktop application:
# Install Newman globally via npm
npm install -g newman newman-reporter-htmlextra
# Execute Postman collection with environment variables and generate HTML report
newman run tests/postman_collection.json \
--environment env/staging.json \
--reporters cli,htmlextra \
--reporter-htmlextra-export reports/api-report.html \
--bail # Exit immediately with non-zero code if critical smoke tests fail11. Frequently Asked Questions (FAQ)
Why is API testing faster and more reliable than UI browser testing?
API tests communicate directly with backend web services using lightweight HTTP payloads (JSON/XML). They bypass browser rendering engines, CSS transitions, JavaScript DOM parsing, and network image downloads. An API test completes in 50 to 200 milliseconds, whereas a comparable UI test takes 3 to 10 seconds. Furthermore, API tests are immune to UI redesigns, CSS class renaming, or layout refactoring, resulting in virtually zero locator-based flakiness.
What is the exact architectural difference between PUT and PATCH?
PUT is an idempotent method designed to completely replace the entire target resource with the provided payload. If you omit a field in a PUT request, that field is either overwritten with null or defaults to system settings. PATCH is a partial update method that modifies only the specific attributes provided in the payload while leaving existing fields unchanged. PUT is idempotent by definition (running it multiple times leaves the server in the identical state), while PATCH can be non-idempotent depending on business logic.
How do you test for Broken Object Level Authorization (BOLA / IDOR) in REST APIs?
BOLA (Broken Object Level Authorization), also known as Insecure Direct Object Reference (IDOR), is the #1 vulnerability on the OWASP API Security Top 10. To test for BOLA: Authenticate as User A and obtain a valid bearer token. Send a request to fetch or mutate User B's resource (e.g., `GET /api/v1/accounts/ACC-USER-B` or `PUT /api/v1/users/USER-B/profile`) using User A's Authorization header. A secure API must return 403 Forbidden or 404 Not Found. If it returns 200 OK with User B's data, a critical BOLA vulnerability exists.
What is JSON Schema Validation and why is it essential in microservices?
JSON Schema validation verifies that an API response adheres to a strict contract defining required field names, expected data types (string, integer, boolean, array), formatting constraints (email, uuid, regex), and allowed nullability. In microservices architectures, teams frequently update backend services. Schema validation catches contract breaking changes (such as a backend developer renaming `userId` to `user_id` or returning null instead of an empty array) before downstream web or mobile apps crash.
What is the purpose of RequestSpecification and ResponseSpecification in REST Assured?
RequestSpecification and ResponseSpecification are builder patterns in REST Assured that centralize common configuration. RequestSpecification bundles the base URI, headers (Authorization, Content-Type), and logging settings so you don't repeat them across dozens of test methods. ResponseSpecification bundles expected baseline assertions, such as verifying status codes under 300, checking Content-Type headers, or validating response time limits.
Ready to Practice API Automation?
Connect your Postman or Java REST Assured test suite directly to TesterRank's live practice APIs across Banking, Shopping, and Insurance.