AlgoInsight

Q&A

What is API testing in software testing?

By AlgoInsight Team2026-06-07rest-apisecuritytestingpython

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

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

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

References

More answers