Trang chủ
QA Learning Hub
Chương 11 · API Testing
Chương 11 Trung Cấp

API Testing

Kiểm thử API là kỹ năng bắt buộc của QA hiện đại — nhanh hơn UI testing, phát hiện bug sớm hơn ở tầng backend.

🌐 HTTP Fundamentals
MethodMục đíchIdempotent?Request Body?
GETRetrieve data — không thay đổi stateYesNo
POSTCreate resource mớiNoYes
PUTUpdate toàn bộ resource (replace)YesYes
PATCHUpdate một phần resourceDependsYes
DELETEXóa resourceYesOptional

Status Codes cần nhớ:

  • 2xx Success200 OK, 201 Created, 204 No Content (DELETE success), 202 Accepted (async)
  • 3xx Redirect301 Moved Permanently, 302 Found (temporary redirect), 304 Not Modified (cache hit)
  • 4xx Client Error400 Bad Request (malformed), 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity (validation fail)
  • 5xx Server Error500 Internal Server Error (bug!), 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout

Headers quan trọng:

  • Content-Type: application/json — Request body là JSON
  • Authorization: Bearer <token> — JWT/OAuth token
  • Accept: application/json — Client muốn nhận JSON
  • X-Request-ID: uuid — Correlation ID cho tracing
  • Cache-Control: no-cache — Không dùng cached response
📮 Postman Advanced
  • Environments & VariablesTạo Environment: Dev, Staging, Production. Variables: {{base_url}}, {{token}}, {{user_id}}. Switch environment = switch full config set instantly.
  • Pre-request ScriptsJavaScript chạy trước request. Dùng để: generate dynamic data, set variables từ kết quả request trước, compute signature/hash.
  • Tests Tab (Assertions)JavaScript assertions chạy sau response. Xem code example dưới.
  • Collection RunnerChạy toàn bộ collection theo thứ tự. Set iterations, delay giữa requests, sử dụng CSV data file.
  • Chaining RequestsExtract data từ response: pm.environment.set("userId", pm.response.json().id). Request sau dùng {{userId}}.
// Postman Tests Tab — Common Assertions // Status code pm.test("Status is 200", () => pm.response.to.have.status(200)); pm.test("Status is 2xx", () => pm.response.to.be.success); // Response time pm.test("Response time < 500ms", () => pm.expect(pm.response.responseTime).to.be.below(500) ); // Body assertions const body = pm.response.json(); pm.test("Has id field", () => pm.expect(body.id).to.exist); pm.test("Email is correct", () => pm.expect(body.email).to.eql("test@example.com") ); pm.test("Status is active", () => pm.expect(body.status).to.be.oneOf(["active", "pending"]) ); // Set variable for next request pm.environment.set("createdId", body.id);
🔑 Authentication Types
  • API KeySimple static key. Truyền qua Header: X-API-Key: abc123 hoặc query param ?api_key=abc123. Test: không có key, key sai, key hết hạn.
  • Bearer Token (JWT)Token sau login: Authorization: Bearer eyJhbGc.... JWT gồm header.payload.signature. Decode payload để verify claims. Test: expired token, tampered payload, wrong signature.
  • Basic AuthAuthorization: Basic base64(username:password). Chỉ an toàn qua HTTPS. Legacy systems. Test: wrong credentials, empty fields.
  • OAuth 2.0Authorization Code (web apps), Client Credentials (server-to-server), Implicit (deprecated), PKCE (mobile/SPA). Test: authorization flow, token refresh, scope validation.
  • OAuth 2.0 Flow1. Client redirects user → Auth Server. 2. User authenticates. 3. Auth Server returns code. 4. Client exchanges code → access_token + refresh_token. 5. Client uses access_token.
🧪 Comprehensive API Test Scenarios
  • Happy Path: Valid request → correct status (200/201), correct response schema, correct data values
  • Auth: No token → 401 | Wrong token → 401 | Expired token → 401 | Valid token wrong role → 403
  • Validation: Missing required field → 400/422 | Wrong data type → 400 | String too long → 400 | Negative number where positive required → 400
  • Not Found: Non-existent ID → 404, not 500
  • Conflict: Create duplicate (same email) → 409, meaningful error message
  • Idempotency: DELETE same ID twice → second call returns 404, not 500
  • Pagination: page=1, page=99999 (beyond data), limit=0, limit=-1, limit=10000 (too large)
  • Filter/Sort: Sort by invalid field → 400 | Filter with SQL injection attempt → 400 or sanitized
  • Large payload: Request body 50MB → should return 413 Payload Too Large
  • Special chars: Unicode, emoji, null bytes in string fields
  • Response schema: All expected fields present | No sensitive data exposed (passwords, tokens, PII)
  • Rate limiting: Send 100+ requests quickly → should get 429 Too Many Requests with Retry-After header
🏆 Senior Insight: Contract Testing

Senior QA biết về Consumer-Driven Contract Testing (Pact.io): Consumer định nghĩa "expectations" về API, Provider verify expectations đó được satisfied. Khi microservices evolve, contracts prevent breaking changes. Đây là layer testing giữa unit test và integration test.

📊 GraphQL Testing

GraphQL khác REST: 1 endpoint, client specify exactly what data needed.

# GraphQL Query { user(id: "123") { id name email orders { id total status } } } # GraphQL Mutation mutation { createOrder(input: { userId: "123" items: [{productId: "456", quantity: 2}] }) { id status total } }

GraphQL-specific Test Cases:

  • Query non-existent field → error với clear message, không crash
  • Deeply nested query (n+1 problem) → performance check
  • Introspection disabled in production → security best practice
  • Query complexity limit — overly complex queries blocked
  • Mutation idempotency — double submit mutation
🤖 API Test Automation
  • Newman CLIChạy Postman collection từ command line: newman run collection.json -e env.json --reporters cli,html. Tích hợp vào CI/CD pipeline.
  • GitHub ActionsTrigger Newman run on PR. Report kết quả vào PR comment. Fail build nếu có test failure.
  • Playwright API TestingPlaywright có built-in API testing: const response = await request.get('/api/users'); — Kết hợp UI và API trong cùng framework.
✏️ Bài Tập
📝 Bài Tập: Postman Collection

Tạo Postman collection test cho một Users API với endpoints: GET /users, POST /users, GET /users/:id, PUT /users/:id, DELETE /users/:id.

  1. Viết test assertions trong Tests tab cho POST /users (successful creation): status code, response body fields, response time
  2. Viết Pre-request Script để generate random email cho mỗi test run tránh duplicate
  3. Chain requests: POST /users → lấy ID từ response → dùng ID trong GET /users/:id
  4. List 8 negative test cases cho DELETE /users/:id endpoint