CYBERSOFT
Đăng nhập

Kiểm thử GraphQL: Query & Mutation cho Tester

Chuyên công nghệGraphQLAPINền tảng
🗓 1 tháng trước21 phút đọc·👁 1,404 lượt xem👤 170 người đọc

Hiểu vì sao GraphQL khác REST (một endpoint, HTTP 200 kể cả khi lỗi), cách khẳng định data + errors, biến, phân quyền theo field, ca âm và bộ công cụ (graphql-request, supertest, Playwright) qua bối cảnh TMĐT.

1. GraphQL là gì dưới góc nhìn Tester

GraphQL là một ngôn ngữ truy vấn cho API và một lớp runtime thực thi truy vấn đó dựa trên một schema định kiểu mạnh. Thay vì nhiều endpoint như REST, một dịch vụ GraphQL thường phơi ra một endpoint duy nhất (ví dụ POST /graphql), và client mô tả chính xác dữ liệu mình cần qua một câu query. Với người kiểm thử, điều quan trọng cần nắm ngay từ đầu là: hợp đồng giữa client và server không nằm ở đường dẫn URL mà nằm ở schema. Schema định nghĩa các kiểu (types), các trường (fields), các thao tác gốc (Query, Mutation, Subscription) và tính nullable của từng trường. Hiểu schema chính là hiểu bề mặt kiểm thử.

Trong bài này chúng ta lấy bối cảnh một hệ thống thương mại điện tử: khách hàng xem sản phẩm, đọc đánh giá, thêm vào giỏ và đặt hàng. Cùng một nghiệp vụ đó, nếu viết bằng REST sẽ cần nhiều lời gọi; còn với GraphQL, client có thể gom về một câu query duy nhất. Sự khác biệt này thay đổi cách bạn thiết kế test: bạn không còn kiểm từng endpoint rời rạc mà kiểm các thao tác (operations) và cách chúng hợp thành dữ liệu trả về. Từ đó, chiến lược kiểm thử của Tester phải xoay quanh việc khẳng định đúng dữ liệu, đúng lỗi và đúng kiểu.

Ba thao tác gốc: Query (đọc dữ liệu), Mutation (ghi/thay đổi dữ liệu), Subscription (nhận dữ liệu theo thời gian thực qua WebSocket). Bài này tập trung vào Query và Mutation vì đó là phần Tester chạm tới nhiều nhất.
REST vs GraphQL — cách gọi khác nhau REST — nhiều endpoint GET /products/42 GET /products/42/reviews GET /users/7/cart 4xx/5xx = lỗi GraphQL — 1 endpoint POST /graphql query { product reviews cart } 1 request → đúng dữ liệu cần HTTP 200 kể cả khi có errors
REST nhiều endpoint vs GraphQL một endpoint

2. GraphQL khác REST ở đâu — dưới lăng kính kiểm thử

Điểm khác biệt gây bất ngờ nhất cho Tester đến từ REST là mã trạng thái HTTP. Trong REST, ta quen dùng status code làm oracle: 200 là thành công, 404 là không tìm thấy, 400 là dữ liệu sai, 401/403 là vấn đề xác thực/ủy quyền. Trong GraphQL, phần lớn triển khai trả về HTTP 200 cho gần như mọi request được parse thành công, kể cả khi bên trong có lỗi nghiệp vụ hay lỗi phân quyền. Lý do là lỗi ở GraphQL được biểu diễn trong thân response ở mảng errors, chứ không phải ở tầng giao vận HTTP. Đây là cái bẫy số một khiến test giả xanh (false green): bạn assert status 200 và tưởng mọi thứ ổn, trong khi errors chứa đầy lỗi.

graphql
# Một operation GraphQL luôn gửi qua POST tới một endpoint duy nhất.
# Client chọn CHÍNH XÁC các field muốn lấy (over-fetch/under-fetch được kiểm soát).
query GetProduct($id: ID!) {
  product(id: $id) {
    id
    title
    price
    reviews(first: 3) {
      rating
      body
    }
  }
}
json
// Payload HTTP thực gửi đi: query + variables (+ operationName nếu có nhiều op)
// POST /graphql   Content-Type: application/json
{
  "query": "query GetProduct($id: ID!){ product(id:$id){ id title price } }",
  "operationName": "GetProduct",
  "variables": { "id": "42" }
}
  • Một endpoint duy nhất — không assert theo URL path mà theo tên operation và cấu trúc dữ liệu.
  • HTTP 200 cho cả thành công lẫn lỗi nghiệp vụ — status code KHÔNG còn là oracle chính.
  • Client tự chọn field — test cần khẳng định đủ và đúng các field yêu cầu, không dư không thiếu.
  • Lỗi nằm trong errors[] của body — oracle thật sự là { data, errors }, không phải header.
  • Kiểu mạnh theo schema — sai kiểu/biến thiếu bị chặn ở tầng validate trước cả khi chạy resolver.
⚠️ Đừng bao giờ chỉ assert response.status === 200 với GraphQL. Luôn assert thêm rằng body.errors là undefined (hoặc rỗng) cho ca thành công, và kiểm nội dung errors cho ca lỗi.

3. Kiểm thử Query — khẳng định dữ liệu đọc

Với một query, mục tiêu kiểm thử đầu tiên là: gửi đúng operation kèm biến, rồi khẳng định phần data trả về đúng hình dạng và đúng giá trị. Ta nên chọn field vừa đủ cho nghiệp vụ đang kiểm, tránh lấy quá nhiều field khiến test giòn (brittle) khi schema mở rộng. Một thói quen tốt là tách biến (variables) ra khỏi chuỗi query để tái sử dụng cùng một query cho nhiều bộ dữ liệu. Việc dùng thư viện graphql-request giúp code test gọn: nó nhận endpoint, query và biến, rồi trả về thẳng phần data, đồng thời ném lỗi nếu có errors — hành vi này rất tiện cho ca happy path.

javascript
// Jest + graphql-request — kiểm một query đọc sản phẩm (happy path)
import { GraphQLClient, gql } from "graphql-request";

const client = new GraphQLClient("http://localhost:4000/graphql");

const GET_PRODUCT = gql`
  query GetProduct($id: ID!) {
    product(id: $id) { id title price }
  }
`;

test("query product trả đúng dữ liệu", async () => {
  // graphql-request ném lỗi nếu response có errors -> happy path an toàn
  const data = await client.request(GET_PRODUCT, { id: "42" });
  expect(data.product).toEqual({ id: "42", title: "Áo thun", price: 199000 });
});

Khi cần toàn quyền kiểm soát cả data lẫn errors (thường cho ca âm), ta gọi thẳng bằng supertest hoặc fetch để đọc trọn response envelope. Với supertest bạn nhắm vào app Express/Apollo, POST body chứa query và variables, rồi assert body.data cùng body.errors một cách tường minh. Cách này bộc lộ rõ triết lý oracle của GraphQL: bạn kiểm cả hai nhánh của cái phong bì { data, errors }.

🔒

Nội dung bị khoá

Bạn đang xem bản xem trước. Đăng nhập để mở khoá toàn bộ bài viết và tất cả tài liệu Tester/QA.

Đã xem 24% nội dung
  • Đọc trọn vẹn mọi bài viết
  • Lưu bài & ghi chú cá nhân
  • Theo dõi tiến độ đã đọc
  • Luyện phỏng vấn, ISTQB, Mock
Đăng nhập để đọc tiếp

Chưa có mã? Lấy mã qua Fanpage / Zalo CyberSoft.

0

💬 Bình luận (0)

Bạn có thể đọc mọi bình luận. Đăng nhập để bình luận

Chưa có bình luận nào. Hãy là người đầu tiên!