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.
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.
# 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
}
}
}// 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.
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.
// 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 }.
💬 Bình luận (0)
Chưa có bình luận nào. Hãy là người đầu tiên!