1. Bối cảnh: vì sao QA cần bộ ba AI agent
Trong một sản phẩm SaaS đa người thuê, đội QA thường phải bao phủ hàng trăm luồng nghiệp vụ: đăng ký, mời thành viên, phân quyền, thanh toán định kỳ, xuất hoá đơn. Viết tay từng kịch bản Playwright vừa chậm vừa dễ lỗi thời khi giao diện thay đổi. Playwright Agents ra đời để chuyển phần lặp đi lặp lại cho AI, còn con người tập trung vào oracle nghiệp vụ. Bài này mổ xẻ ba tác nhân Planner, Generator và Healer, cách chúng hợp tác và ranh giới an toàn khi tin tưởng chúng.
Điểm mấu chốt cần nhớ ngay từ đầu: agent không thay thế tư duy kiểm thử. Chúng tăng tốc việc soạn thảo, nhưng oracle — điều bạn khẳng định là đúng — vẫn phải do con người định nghĩa. Một bài kiểm thử khẳng định 'màn hình hiện thành công' gần như vô giá trị; một bài khẳng định 'số dư sau chuyển tiền được bảo toàn' mới có sức mạnh phát hiện lỗi. Ba agent giúp bạn tới bước khẳng định nhanh hơn, chứ không nghĩ hộ bạn nên khẳng định gì.
2. Khởi tạo: npx playwright init-agents và seed.spec.ts
Lệnh init-agents dựng khung cấu hình cho ba agent và sinh một tệp seed.spec.ts chứa fixtures dùng chung: đăng nhập sẵn, dữ liệu mẫu, thiết lập tenant. seed.spec.ts là điểm neo (grounding) để agent không phải mò lại bước đăng nhập trong mỗi phiên. Nó cũng là nơi bạn khai báo các trạng thái nghiệp vụ mà agent được phép giả định là đã sẵn sàng, ví dụ 'đã có một khách hàng hạng Pro với hạn mức API'.
# Khởi tạo bộ ba agent trong dự án đã có Playwright
npx playwright init-agents
# Sinh ra (rút gọn):
# .playwright/agents/planner.md
# .playwright/agents/generator.md
# .playwright/agents/healer.md
# tests/seed.spec.ts <- fixtures dùng chung
# playwright.config.ts <- thêm project "agents"// tests/seed.spec.ts — grounding cho agent: đăng nhập & seed tenant.
import { test as base, expect } from "@playwright/test";
type Fixtures = { proTenant: { orgId: string; apiQuota: number } };
export const test = base.extend<Fixtures>({
proTenant: async ({ request }, use) => {
// Tạo tenant Pro có hạn mức API xác định (idempotent theo orgId).
const res = await request.post("/api/test/seed", {
data: { plan: "pro", apiQuota: 10_000, seedKey: "pro-agents" },
});
expect(res.ok()).toBeTruthy();
const tenant = await res.json();
await use({ orgId: tenant.orgId, apiQuota: tenant.apiQuota });
},
});
export { expect };3. Planner: khảo sát ứng dụng và viết kế hoạch Markdown
Planner mở ứng dụng thật, điều hướng qua các màn hình, đọc cây khả truy cập (accessibility tree) và viết ra một kế hoạch kiểm thử dạng Markdown. Kế hoạch này liệt kê các luồng, điều kiện tiên quyết, dữ liệu cần và các điểm cần khẳng định. Vì đầu ra là Markdown chứ không phải code, con người có thể đọc và sửa nhanh trước khi cho Generator sinh spec. Đây là chốt kiểm soát quan trọng nhất: bạn nắn ý định kiểm thử tại đây.
# Plan: Recurring billing — invoice generation
## Precondition
- Fixture: proTenant (plan=pro, apiQuota=10000)
- One active subscription, billing day = today
## Flow: monthly invoice
1. Advance clock to billing day
2. Trigger billing job (POST /api/billing/run)
3. Open Billing > Invoices
## Oracle (assert BUSINESS invariants, not "success")
- Exactly ONE invoice created for the period (idempotent re-run)
- invoice.total == sum(lineItems) AND tax computed per region table
- Ledger stays double-entry: debit(AR) == credit(Revenue+Tax)
- No invoice for cancelled subscriptionsChú ý phần Oracle trong kế hoạch trên. Planner có xu hướng đề xuất các khẳng định hời hợt kiểu 'thấy hoá đơn hiện ra'. Nhiệm vụ của bạn khi duyệt là nâng cấp chúng thành bất biến nghiệp vụ: đúng một hoá đơn cho kỳ, tổng tiền bằng tổng dòng, sổ cái cân đối kép. Nếu bỏ qua bước nắn oracle này, toàn bộ giá trị của tự động hoá sẽ tan biến vì test xanh nhưng vô nghĩa.
💬 Bình luận (0)
Chưa có bình luận nào. Hãy là người đầu tiên!