CYBERSOFT
Đăng nhập

Kiểm thử Schema & Contract cho GraphQL

Chuyên nâng caoGraphQLContract/PACTNâng cao
🗓 1 tháng trước21 phút đọc·👁 1,233 lượt xem👤 187 người đọc

Kiểm ở tầng hợp đồng: xác thực SDL, nullability & deprecation, phát hiện breaking change bằng graphql-inspector, contract hướng consumer, kiểm qua introspection và dựng cổng CI — qua bối cảnh nền tảng SaaS đa client.

1. Từ kiểm operation đến kiểm hợp đồng

Ở tầng operation, ta kiểm từng query và mutation trả đúng data và errors. Nhưng khi một API GraphQL phục vụ nhiều nhóm client (web, mobile, đối tác), rủi ro lớn nhất không phải một resolver sai mà là một thay đổi schema vô tình phá vỡ client đang chạy. Vì hợp đồng của GraphQL nằm trọn trong schema, ta có thể kiểm chính schema như một tài sản kiểm thử: nó có build hợp lệ không, nullability và deprecation có đúng chủ đích không, và một thay đổi mới có phá vỡ phiên bản trước không. Đây là tầng kiểm hợp đồng (contract testing) — trọng tâm của bài nâng cao này, đặt trong bối cảnh một nền tảng SaaS đa client.

Schema (SDL) là hợp đồng — nguồn sự thật kiểm thử type Product { id: ID! title: String! sku: String @deprecated price: Money! } Kiểm ở tầng hợp đồng • SDL build hợp lệ (buildSchema) • nullability & @deprecated đúng • diff phát hiện breaking change • introspection khớp SDL đã duyệt CI gate chặn merge nếu phá vỡ
Schema SDL là hợp đồng và các loại kiểm ở tầng hợp đồng
SDL (Schema Definition Language) là cú pháp văn bản mô tả schema GraphQL: type, field, kiểu, nullability (dấu !), directive như @deprecated. Ta có thể lưu SDL vào repo và version-control như một hợp đồng công khai.

2. Vì sao schema là bề mặt kiểm thử tối quan trọng

Trong REST, hợp đồng thường rải rác qua tài liệu OpenAPI, và việc phá vỡ có thể âm thầm. Với GraphQL, schema là một artifact máy đọc được, có cấu trúc, cho phép so sánh (diff) hai phiên bản một cách chính xác. Nhờ đó, phát hiện thay đổi phá vỡ trở nên tự động hóa được. Với Tester, điều này mở ra một loại test cực kỳ giá trị mà REST khó có: mỗi lần đội dev sửa schema, ta so nó với phiên bản đã duyệt và phân loại thay đổi. Xóa một field mà client đang dùng, đổi kiểu, hay biến một argument từ nullable thành bắt buộc — tất cả là breaking và phải bị chặn trước khi lên production.

graphql
# schema.graphql — SDL được version-control như hợp đồng công khai
type Query {
  workspace(id: ID!): Workspace
  plans: [Plan!]!
}

type Workspace {
  id: ID!
  name: String!
  seats: Int!
  legacyKey: String @deprecated(reason: "Dùng apiKey thay thế")
  apiKey: String!
}

type Plan { id: ID!  name: String!  monthlyPrice: Int! }
💡 Coi schema.graphql như một hợp đồng được review trong pull request. Mọi thay đổi schema phải đi kèm diff dễ đọc để reviewer thấy ngay điều gì được thêm, đánh dấu deprecated hay xóa.

3. Kiểm tính hợp lệ của SDL

Kiểm cơ bản nhất ở tầng hợp đồng là: SDL có build được thành schema hợp lệ không. Thư viện graphql (graphql-js) cung cấp buildSchema để dựng schema từ chuỗi SDL; nếu có lỗi cú pháp, tham chiếu kiểu không tồn tại, hoặc vi phạm quy tắc, nó sẽ ném lỗi. Đây là một smoke test rẻ mà mọi dự án GraphQL nên có: chạy trước khi triển khai để chắc chắn schema không hỏng. Ngoài build, ta có thể duyệt qua type map để khẳng định các type và field bắt buộc tồn tại đúng như hợp đồng mong đợi.

javascript
// Smoke test SDL: build được + type/field bắt buộc tồn tại
import { readFileSync } from "node:fs";
import { buildSchema } from "graphql";

test("SDL build hợp lệ và có type bắt buộc", () => {
  const sdl = readFileSync("./schema.graphql", "utf8");
  const schema = buildSchema(sdl);          // ném lỗi nếu SDL sai

  const Workspace = schema.getType("Workspace");
  expect(Workspace).toBeDefined();
  const fields = Workspace.getFields();
  expect(fields.id).toBeDefined();
  expect(fields.apiKey).toBeDefined();
  // apiKey phải non-null theo hợp đồng
  expect(String(fields.apiKey.type)).toBe("String!");
});

Việc assert String(fields.apiKey.type) === 'String!' minh họa cách kiểm nullability ở cấp hợp đồng: dấu ! nghĩa là non-null. Một field đổi từ String! sang String (bỏ non-null) tưởng vô hại cho phía server nhưng lại có thể phá client vốn giả định trường luôn có giá trị. Ngược lại, một argument đổi từ nullable sang non-null là breaking cho caller. Kiểm nullability tường minh giúp bắt sớm các thay đổi tinh vi này.

4. Nullability & deprecation — kiểm chủ đích thiết kế

Nullability trong GraphQL không chỉ là chi tiết kỹ thuật mà là quyết định thiết kế hợp đồng. Một field non-null (kiểu T!) hứa với client rằng nó không bao giờ null; nếu resolver trả null cho field non-null, cả object cha có thể bị null-hóa (bubble up), gây lỗi lan rộng. Vì thế, Tester nên kiểm rằng những field cam kết non-null thực sự luôn có giá trị dưới mọi ca (kể cả ca lỗi phụ), và những field có thể vắng mặt hợp lệ được khai nullable. Deprecation qua directive @deprecated là cách báo cho client rằng một field sắp bị gỡ; kiểm rằng field deprecated vẫn hoạt động (chưa xóa) và lý do deprecation được nêu rõ.

🔒

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 23% 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!