Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

API Testing Fundamentals cho QA

Software Testing Fundamentals Bài 49/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn đang test một ứng dụng đặt vé xem phim. Bạn mở app, chọn phim, chọn ghế, bấm thanh toán — và tất cả những gì bạn "nhìn thấy" chỉ là màn hình. Nhưng đằng sau cái màn hình đẹp đẽ đó, có hàng chục cuộc "trò chuyện" âm thầm diễn ra giữa app và máy chủ: app hỏi "còn ghế nào trống không?", máy chủ trả lời "ghế A1, A2 hết rồi, còn A3 tới A10"; app hỏi tiếp "khóa ghế A5 cho user này trong 5 phút nhé?", máy chủ đồng ý. Những cuộc trò chuyện đó chính là API (Application Programming Interface) — và việc kiểm tra chúng gọi là API Testing.

Với một QA, API Testing là kỹ năng "nâng cấp" cực kỳ đáng giá. Suốt các bài trước bạn đã học rất nhiều về test qua giao diện (UI). Nhưng UI chỉ là phần nổi của tảng băng. Phần lớn logic nghiệp vụ — tính tiền, kiểm tra tồn kho, xác thực người dùng, trừ điểm tích lũy — nằm ở tầng backend, và API là cánh cửa duy nhất để bạn gõ thẳng vào tầng đó mà không phải "đi vòng" qua giao diện.

Tại sao điều này quan trọng đến vậy? Vì test ở tầng API cho bạn bốn thứ mà UI test khó lòng mang lại: kiểm tra logic độc lập với giao diện, tốc độ nhanh hơn UI test từ 10 đến 100 lần, độ ổn định cao hơn (giao diện hay đổi nút, đổi màu, còn hợp đồng API thì ổn định hơn nhiều), và khả năng phủ (cover) những trường hợp biên (edge case) mà qua UI gần như không thể tạo ra. Bài này sẽ cho bạn nền tảng vững để bắt đầu — không cần biết lập trình sâu, chỉ cần hiểu bản chất và biết dùng công cụ.

Khái niệm cốt lõi

API là gì và HTTP hoạt động ra sao

Trong thế giới web hiện đại, phần lớn API mà QA gặp là REST API giao tiếp qua giao thức HTTP/HTTPS. Bạn có thể hình dung mỗi lời gọi API là một lá thư gửi đi và một lá thư nhận về. Lá thư gửi đi (request) gồm bốn thành phần chính:

  • Method (phương thức): cho biết bạn muốn làm gì. GET để lấy dữ liệu, POST để tạo mới, PUT/PATCH để cập nhật, DELETE để xóa.
  • URL/Endpoint: địa chỉ tài nguyên, ví dụ https://api.tiki.vn/v2/products/12345.
  • Headers: thông tin đi kèm, ví dụ Authorization: Bearer <token> để chứng minh bạn là ai, hay Content-Type: application/json để nói định dạng dữ liệu.
  • Body: nội dung dữ liệu gửi lên (thường ở dạng JSON), ví dụ thông tin sản phẩm cần tạo.
Lá thư nhận về (response) cũng có ba phần cần quan tâm: status code (mã trạng thái), headers, và body (dữ liệu trả về).

Status code — ngôn ngữ báo hiệu của server

Đây là thứ QA phải thuộc nằm lòng. Status code được chia thành các nhóm:

  • 2xx — Thành công: 200 OK (yêu cầu ổn), 201 Created (đã tạo mới thành công), 204 No Content (thành công nhưng không trả nội dung).
  • 3xx — Chuyển hướng: 301, 302.
  • 4xx — Lỗi phía client (người gọi): 400 Bad Request (dữ liệu gửi lên sai), 401 Unauthorized (chưa đăng nhập/token sai), 403 Forbidden (đã đăng nhập nhưng không có quyền), 404 Not Found (không tìm thấy tài nguyên), 409 Conflict (xung đột, ví dụ tạo trùng), 422 Unprocessable Entity (dữ liệu đúng định dạng nhưng sai nghiệp vụ), 429 Too Many Requests (bị chặn vì gọi quá nhiều).
  • 5xx — Lỗi phía server: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable.
Một mẹo phân biệt vàng: 401 là "tôi không biết bạn là ai", còn 403 là "tôi biết bạn là ai nhưng bạn không được phép". Và 400 là lỗi của người gọi, 500 là lỗi của người viết server — phân biệt đúng điều này giúp bug report của bạn chỉ đúng người chịu trách nhiệm.

JSON — định dạng dữ liệu bạn sẽ gặp mỗi ngày

Hầu hết API ngày nay trả về dữ liệu dạng JSON — một cấu trúc gồm cặp "khóa": giá trị. Ví dụ:

{
  "order_id": 88213,
  "status": "PAID",
  "total": 350000,
  "items": [
    { "sku": "VE-A5", "price": 175000 }
  ]
}

QA cần biết đọc JSON để kiểm tra: giá trị có đúng không, kiểu dữ liệu có đúng không (số ra số, chuỗi ra chuỗi), trường bắt buộc có bị thiếu không, và cấu trúc có khớp với tài liệu (spec) không.

Contract testing và tài liệu API

Mỗi API có một "hợp đồng" (contract) — quy định request phải trông thế nào và response sẽ trả về thế nào. Tài liệu này thường viết theo chuẩn OpenAPI/Swagger. Là QA, việc đầu tiên khi test một API mới là đọc kỹ tài liệu này: có những endpoint nào, tham số bắt buộc là gì, giá trị hợp lệ ra sao. Test API mà không có spec giống như đi thi mà không biết đề — bạn sẽ chỉ đoán mò.

Công cụ của QA

Với người mới, hai công cụ phổ biến nhất ở Việt Nam là Postman (giao diện trực quan, dễ học, có thể lưu collection, tạo environment, viết test script đơn giản bằng JavaScript) và cURL (dòng lệnh, gọn nhẹ, tiện để lập trình viên tái hiện bug). Ngoài ra còn có Insomnia, hoặc thư viện REST Assured (Java) cho automation. Ở bài này chúng ta tập trung vào tư duy và Postman.

Tình huống thực tế

Tình huống 1: Sàn TMĐT và cái giá 0 đồng

Một sàn thương mại điện tử tầm trung ở TP.HCM (gọi là ShopViet) có tính năng áp mã giảm giá. Qua UI, tester chỉ thử được các mã có sẵn trong danh sách và thấy mọi thứ đều ổn — giảm 10%, giảm 50k, đều đúng. Nhưng khi một QA có kinh nghiệm API mở Postman và gọi thẳng endpoint POST /cart/apply-coupon với body chứa mã giảm giá 200% (một giá trị mà UI không bao giờ cho nhập vì dropdown chỉ có các mức cố định), server vui vẻ trả về 200 OK và tổng đơn hàng thành -45.000đ. Nghĩa là hệ thống sẵn sàng "trả tiền" cho khách mua hàng.

Diễn giải: lỗi này bị giấu kín sau UI vì giao diện đã "lọc" bớt input xấu. Nhưng API là cửa mở — kẻ tấn công hoặc một app bên thứ ba có thể gọi thẳng vào đây. Validation (kiểm tra dữ liệu) phải nằm ở backend, không được chỉ dựa vào frontend.

Bài học rút ra: UI có thể che giấu edge case, nhưng API thì phơi bày tất cả. Test API cho phép bạn tấn công thẳng vào logic mà giao diện không cho phép chạm tới. Validation ở frontend chỉ để trải nghiệm mượt, còn "chốt chặn thật" phải ở backend.

Tình huống 2: Startup fintech và bài toán tốc độ

Một startup fintech ở Hà Nội có bộ hồi quy (regression) 400 test case UI chạy bằng Selenium, mất khoảng 3 giờ 20 phút mỗi lần và thường xuyên "flaky" — cứ 10 lần chạy thì 2-3 lần đỏ giả vì trang load chậm, popup che nút, hoặc animation chưa kịp xong. Đội QA quyết định phân tích: trong 400 case đó, có tới 260 case thực chất chỉ kiểm tra logic nghiệp vụ (tính lãi suất, kiểm tra hạn mức, xác thực OTP) chứ không liên quan gì đến hiển thị. Họ chuyển 260 case này xuống tầng API.

Kết quả sau một tháng: bộ API test 260 case chạy trong khoảng 4 phút, tỉ lệ flaky gần như bằng 0. Bộ UI còn lại 140 case (những case thật sự cần kiểm giao diện) rút xuống còn hơn 1 giờ. Tổng thời gian cho một vòng regression giảm từ 3 giờ 20 xuống dưới 1 giờ 10.

Diễn giải: con số "nhanh hơn 10–100 lần" không phải nói cho vui. UI test phải khởi động trình duyệt, render, chờ đợi; API test chỉ gửi và nhận gói tin. Với cùng một logic, chênh lệch tốc độ là rất lớn.

Bài học rút ra: Hãy đẩy việc kiểm tra logic xuống tầng thấp nhất có thể. Nếu một case không cần "mắt nhìn" giao diện, nó nên là API test. Điều này liên hệ chặt với tư duy tháp kiểm thử (Test Pyramid) — API/integration test là tầng giữa vững chắc, còn UI/E2E test nên ít và tinh.

Tình huống 3: App gọi xe và trạng thái không thể tái hiện trên UI

Một đội QA cho app gọi xe cần test tình huống: tài xế đã nhận chuyến, nhưng đúng lúc đó server bên thanh toán trả về 503 Service Unavailable. Qua UI, để tạo được đúng khoảnh khắc này gần như bất khả thi — bạn không thể canh đúng mili-giây tài xế bấm nhận rồi làm sập cổng thanh toán. Nhưng ở tầng API, QA phối hợp với dev dùng công cụ mock để giả lập endpoint thanh toán trả về 503, rồi gọi tuần tự các API theo đúng kịch bản. Họ phát hiện: khi thanh toán lỗi, hệ thống vẫn chuyển trạng thái chuyến đi sang "đang di chuyển", dẫn đến chuyến đi "ma" không thu được tiền.

Diễn giải: nhiều edge case liên quan đến lỗi hệ thống, timeout, race condition (đua tranh trạng thái) chỉ có thể dựng lên ở tầng API bằng cách kiểm soát trực tiếp response và thứ tự gọi.

Bài học rút ra: API testing mở khóa những edge case mà UI test không bao giờ chạm tới — đặc biệt là các kịch bản lỗi và trạng thái trung gian.

Hướng dẫn từng bước

Đây là quy trình để bạn test một endpoint từ đầu, lấy ví dụ endpoint tạo đơn hàng POST /api/v1/orders:

  • Đọc tài liệu (spec) trước tiên. Xác định: method, URL, header bắt buộc (thường là AuthorizationContent-Type), các trường trong body (bắt buộc/tùy chọn, kiểu dữ liệu, ràng buộc giá trị), và response mong đợi cho từng tình huống.
  • Thiết lập môi trường trong Postman. Tạo một Environment chứa các biến như base_url, token. Dùng biến thay vì hardcode để dễ chuyển giữa môi trường dev, staging, production.
  • Lấy token xác thực. Gọi endpoint đăng nhập (ví dụ POST /auth/login), lấy token từ response và lưu vào biến token.
  • Test happy path (đường đi thuận lợi) trước. Gửi một request hợp lệ đầy đủ. Kiểm tra: status code có phải 201 không, body trả về có order_id không, status có đúng là PENDING không.
  • Kiểm tra kỹ response, không chỉ status code. Đây là lỗi kinh điển của người mới: thấy 200 là cho pass. Phải kiểm cả nội dung — giá trị đúng chưa, kiểu dữ liệu đúng chưa, trường bắt buộc có đủ không.
  • Test các trường hợp âm (negative test). Gửi thiếu trường bắt buộc (mong đợi 400/422), gửi sai token (mong đợi 401), gửi giá trị biên (số lượng = 0, = -1, cực lớn), gửi sai kiểu (gửi chữ vào trường số).
  • Kiểm tra phân quyền. Dùng token của user A cố gắng thao tác trên tài nguyên của user B (mong đợi 403). Đây là lỗ hổng cực kỳ phổ biến gọi là IDOR.
  • Viết test script để tự động hóa. Trong tab Tests của Postman, viết vài dòng đơn giản như pm.test("Status 201", () => pm.response.to.have.status(201));.
  • Gom thành Collection và chạy hàng loạt bằng Collection Runner, tiến tới đưa vào pipeline CI để chạy tự động.

Lỗi thường gặp & mẹo

  • Chỉ nhìn status code, bỏ qua body. 200 OK không có nghĩa dữ liệu đúng. Server có thể trả 200 kèm một message lỗi bên trong body. Luôn kiểm nội dung.
  • Quên test negative case. Người mới thích test happy path vì nó "chạy được". Nhưng bug thật sự ẩn ở các case âm: thiếu field, sai kiểu, giá trị biên, token hết hạn. Đây mới là nơi API testing tỏa sáng.
  • Test trên production mà không cẩn thận. Một request DELETE gọi nhầm môi trường có thể xóa dữ liệu thật. Luôn kiểm tra biến base_url đang trỏ đâu trước khi bấm Send.
  • Hardcode token và dữ liệu. Token hết hạn, môi trường đổi — cả collection sập. Hãy dùng biến environment và tự động lấy token qua request đăng nhập.
  • Bỏ qua header. Rất nhiều lỗi 415, 401 đến từ việc thiếu Content-Type hoặc Authorization. Kiểm header như kiểm body.
  • Không kiểm tính idempotent với các thao tác nhạy cảm. Gọi POST /payment hai lần liên tiếp có tạo ra hai giao dịch trùng không? Đây là edge case đáng tiền — hãy luôn thử gọi lặp.
  • Mẹo báo bug: khi report bug API, hãy đính kèm câu lệnh cURL đầy đủ (che token nhạy cảm). Dev chỉ cần copy-paste là tái hiện được ngay, rút ngắn thời gian sửa rất nhiều.
  • Mẹo kiểm response time: ngay cả khi chưa làm performance test bài bản, hãy để ý thời gian phản hồi trong Postman. Một endpoint bình thường trả trong vài trăm mili-giây; nếu thấy 3-4 giây, đó là dấu hiệu cần báo.

Bài tập thực hành

  • Làm quen công cụ: Cài Postman. Dùng một API công khai miễn phí (ví dụ https://jsonplaceholder.typicode.com/posts). Gửi lần lượt GET, POST, PUT, DELETE và ghi lại status code cùng body của từng lời gọi.
  • Phân tích spec: Cho một endpoint giả định POST /users với các trường bắt buộc email (chuỗi, đúng định dạng email), age (số nguyên, 18–100), phone (chuỗi 10 số). Hãy liệt kê ít nhất 12 test case, bao gồm happy path và các case âm (thiếu field, sai kiểu, giá trị biên, sai định dạng).
  • Viết checklist status code: Với endpoint đăng nhập POST /auth/login, hãy chỉ ra input tương ứng để tạo ra từng mã: 200, 400, 401, 429.
  • Tư duy edge case qua API: Quay lại tình huống mã giảm giá 200% ở trên. Hãy viết 5 test case tấn công logic coupon mà UI không cho nhập (giá trị âm, mã hết hạn, mã đã dùng, áp nhiều mã cùng lúc, giá trị vượt tổng đơn).
  • Tự động hóa nhỏ: Trong Postman, viết test script kiểm tra một response GET trả về đúng 200, có trường id kiểu số, và response time dưới 800ms.

Tóm tắt

API Testing là bước tiến quan trọng biến bạn từ một tester "bấm nút" thành một QA hiểu bản chất hệ thống. Bạn đã học được: API là các cuộc trò chuyện HTTP giữa client và server, với request (method, URL, header, body) và response (status code, header, body); ý nghĩa các nhóm status code 2xx/4xx/5xx và cách phân biệt các mã hay nhầm như 401 với 403, 400 với 500; cách đọc JSON và tầm quan trọng của tài liệu spec; cùng quy trình test một endpoint từ happy path đến negative case và phân quyền.

Quan trọng nhất là bốn lý do khiến API testing đáng giá: kiểm tra logic độc lập với UI, nhanh hơn UI test 10–100 lần, ổn định hơn vì hợp đồng API ít đổi hơn giao diện, và phủ được những edge case mà UI không thể tạo ra — như ba tình huống về coupon 200%, regression từ 3 giờ xuống 4 phút, và chuyến xe "ma" khi thanh toán lỗi đã minh họa. Hãy mở Postman lên và bắt đầu thực hành ngay hôm nay; đây là kỹ năng sẽ theo bạn suốt sự nghiệp QA.