·

Tiếng Việt: Prompt-driven test charters and session guides

Prompt-driven test charters and session guides

Nếu bạn đã từng ngồi trước một tính năng mới ra release note, mở trình duyệt lên và tự hỏi "giờ test cái gì trước" — thì charter chính là câu trả lời có cấu trúc cho câu hỏi đó. Nhưng viết charter tốt tốn thời gian, và phần lớn charter do con người viết ra lại khá hời hợt: "Test tính năng checkout", "Kiểm tra flow đăng nhập". Chúng thiếu mission rõ ràng, thiếu ràng buộc thời gian, và không định hướng được rủi ro cụ thể.

Bài học này đi sâu vào cách dùng AI như một "charter-writing partner": từ việc hiểu tại sao charter do người viết thường yếu, đến cách nạp context nhiều lớp để AI sinh ra charter sắc bén, cách điều chỉnh charter cho từng loại nền tảng (web, API, mobile, CTV), và cuối cùng — cách dùng charter để dẫn dắt một session khám phá mà không biến nó thành một checklist cứng nhắc, giết chết trực giác exploratory testing.

Test Charter Là Gì và AI Tạo Ra Charter Tốt Hơn Như Thế Nào?

Charter (bản giao nhiệm vụ khám phá) là một khái niệm cốt lõi trong exploratory testing theo trường phái Session-Based Test Management (SBTM) của James Bach và Jonathan Bach. Một charter tốt trả lời được ba câu hỏi: khám phá cái gì, bằng cách nào, và để tìm ra loại vấn đề gì. Nó không phải test case — nó là một "nhiệm vụ có định hướng nhưng mở", cho phép tester dùng trực giác và phản xạ trong lúc thực thi.

Vì sao Charter do con người viết thường yếu

Tôi từng review hàng trăm test charter được viết bởi các đội QA khác nhau, và mẫu số chung của charter yếu luôn là ba lỗi sau:

  1. Quá rộng, không có biên: "Explore search feature" — search có filter, sort, pagination, autocomplete, phân quyền theo role... test hết trong 60 phút là bất khả thi. Charter kiểu này khiến tester lạc trong "session mù", đi lan man mà không tích lũy được insight có giá trị.
  2. Không gắn với rủi ro cụ thể: Charter không nói rõ đang lo sợ điều gì. Một charter như "Test payment flow" không cho tester biết nên tập trung vào race condition khi double-click nút Pay, hay vào việc số tiền hiển thị sai đơn vị tiền tệ khi đổi locale.
  3. Thiếu tín hiệu "khi nào dừng": Không có oracle (tiêu chí đối chiếu) hay heuristic nào được gợi ý, nên tester không biết đâu là "bug thật" và đâu là "chuyện bình thường của UI".

Nguyên nhân sâu xa: con người viết charter dựa trên kinh nghiệm rời rạc, thường trong 5-10 phút trước standup, thiếu thời gian đọc lại spec, đọc lại code diff, hay tra cứu lịch sử bug. AI không có giới hạn đó — nó có thể "đọc" toàn bộ spec, PR diff, và bug tracker trong vài giây, rồi tổng hợp ra một charter có định hướng rủi ro rõ ràng.

Giải phẫu một Charter do AI sinh ra

Một charter tốt do AI tạo ra thường có cấu trúc 5 phần, khác hẳn với câu charter một dòng truyền thống:

CHARTER: Explore quantity-based discount tiers in the cart when items
are added/removed rapidly across sessions.

MISSION: Discover inconsistencies between displayed discount tier and
actual applied discount when cart quantity crosses tier thresholds
(5, 10, 20 units) via multiple update paths (cart page, quick-add,
saved-cart restore).

TIME-BOX: 45 minutes

RISK HYPOTHESIS:
- Discount tier calculated server-side may lag behind optimistic UI
  update, causing a "flash" of wrong price that then corrects — but
  might not correct in some code paths (e.g., PayPal express checkout
  skips a re-render).
- Removing items to drop below a threshold might not trigger
  discount recalculation if cart state is cached client-side.

ORACLES / HEURISTICS TO APPLY:
- Consistency heuristic: displayed subtotal, discount label, and
  final total must always agree with server-computed cart state.
- History heuristic: compare against the discount tiers as
  documented in PROD-4821 (previous ticket that changed thresholds
  from 3/8/15 to 5/10/20).

OUT OF SCOPE: Tax calculation, shipping discounts, coupon stacking
(covered by separate charters).

So với "Test discount trong cart", charter này cho tester một mission cụ thể, một giả thuyết rủi ro để bám theo (không phải để chứng minh đúng mà để dò), và ranh giới rõ ràng về phạm vi. Đây chính là khác biệt giữa charter "mở nhưng vô định hướng" và charter "mở nhưng có la bàn".

Prompt Pattern: Generating a Single Focused Charter

Khi bạn cần một charter cho một khu vực cụ thể (ví dụ một tính năng vừa được đội dev báo "done"), dùng prompt pattern sau. Chìa khóa là yêu cầu AI phải sinh ra risk hypothesis trước khi viết charter, không phải charter trước rồi risk sau.

You are an experienced exploratory tester using Session-Based Test
Management. I need ONE focused test charter for the following area:

AREA: [tên tính năng / module]
CONTEXT: [1-2 câu mô tả tính năng làm gì]
RECENT CHANGE: [mô tả PR/thay đổi gần nhất nếu có]

Generate a single charter with this exact structure:
1. CHARTER (one sentence, action + area + condition)
2. MISSION (2-3 sentences: what inconsistency or failure mode we're
   hunting for, phrased as a discovery goal, not a pass/fail check)
3. TIME-BOX (recommend 30, 45, 60, or 90 minutes based on scope)
4. RISK HYPOTHESIS (2-4 bullet points: specific ways this could break,
   grounded in the context I gave you — not generic "might have bugs")
5. ORACLES/HEURISTICS (name 2-3 concrete heuristics relevant to this
   area — e.g. consistency, history, familiar-problems, explainability)
6. OUT OF SCOPE (what to explicitly NOT chase in this session)

Keep the charter narrow enough to meaningfully cover in the time-box.
If the area is too broad for one charter, tell me so instead of
writing a shallow one, and suggest how to split it.

Mẹo: Luôn thêm câu cuối "If the area is too broad... tell me so" — đây là câu quan trọng nhất trong cả prompt. Không có nó, AI có xu hướng "cố gắng làm hài lòng" bằng cách nhồi một charter mơ hồ để phủ hết phạm vi rộng bạn đưa ra, thay vì thẳng thắn báo cần chia nhỏ.

Generating a Suite of Charters for a Feature

Với một tính năng lớn (ví dụ toàn bộ luồng "đăng ký gói Premium"), một charter là không đủ. Bạn cần một bộ charter phủ các góc nhìn khác nhau — happy path, edge case, cross-cutting concern (bảo mật, hiệu năng, khả năng tiếp cận). Prompt sau giúp AI tự phân rã:

You are planning an exploratory testing charter suite for this
feature: [mô tả tính năng đầy đủ, kèm link/nội dung spec nếu có].

Generate a suite of 6-10 charters that together give balanced
coverage across these dimensions:
- Happy path variations (different valid user paths)
- Edge cases and boundary conditions
- Error handling and recovery
- Cross-feature interaction (what else touches this data/state)
- Non-functional angles relevant here (performance, security,
  accessibility — only include if genuinely relevant)

For each charter, give: title, one-line mission, suggested time-box,
and a priority (P1/P2/P3) based on likely user impact if broken.
Order the list by priority. Flag any charter that depends on another
charter being run first (e.g. "requires charter #3 state").

Kết quả trả về thường là một bảng charter có thể đưa thẳng vào bảng theo dõi session (Session sheet) của team. Điểm mạnh của cách làm này: AI tự nhiên tách được các charter theo chiều "không chồng lấn" — thứ mà con người khi brainstorm nhanh hay bị lặp ý.

Cung cấp Feature Context như thế nào để AI sinh Charter tập trung, có nhận diện rủi ro?

Charter chỉ tốt bằng context bạn đưa vào. Đây là phần quan trọng nhất của cả bài học: một charter "sáng tạo" và "chung chung" có nguyên nhân gốc rễ là context nghèo. AI không tự nhiên biết đội bạn từng bị bug gì, code vừa đổi gì, hay ai dùng sản phẩm này theo cách khác thường. Bạn phải nạp bốn lớp context sau.

Context Layer 1: Đặc tả tính năng hoặc User Story

Đây là lớp nền — giúp AI hiểu "đúng" là gì trước khi đi tìm "sai". Dán trực tiếp nội dung ticket Jira, PRD, hoặc Acceptance Criteria. Đừng tóm tắt lại bằng lời của bạn — bản gốc thường chứa những chi tiết nhỏ (một điều kiện biên được ghi trong AC thứ 5, một câu note "chỉ áp dụng cho user Việt Nam") mà bạn dễ bỏ sót khi paraphrase.

Ví dụ input:

FEATURE SPEC (from Jira PROD-5510):
As a subscriber, I want to pause my subscription for up to 3 months
so that I don't lose my account history when I travel.

Acceptance Criteria:
- Pause available only for annual plans, not monthly
- Max pause duration: 90 days, selectable in 30-day increments
- During pause: no billing occurs, content history retained,
  cannot access premium content
- User can resume early at any time
- Auto-resume triggers billing on day 91 if not manually resumed
- Pause option hidden if user has an active refund request

Context Layer 2: Mô tả thay đổi code

Nếu bạn có quyền truy cập PR diff hoặc changelog, đưa vào — đây là nguồn tín hiệu rủi ro giàu nhất mà charter thủ công hầu như không bao giờ dùng tới, vì con người ít khi đọc diff trước khi test. AI thì đọc được và liên kết được dòng code với hành vi rủi ro.

CODE CHANGE SUMMARY (from PR #2291):
- Added `pause_end_date` column to subscriptions table
- Billing cron job (runs daily 02:00 UTC) now checks
  `pause_end_date IS NOT NULL AND pause_end_date < NOW()` before
  charging
- Frontend: new "Pause subscription" button added to Account page,
  calls PATCH /api/subscriptions/:id/pause
- Existing "Cancel subscription" flow NOT modified, but shares the
  same subscriptions table
- No new index added on pause_end_date column

Mẹo: Câu "No new index added on pause_end_date column" nhìn tưởng chỉ là chi tiết kỹ thuật, nhưng khi đưa vào prompt, một AI được yêu cầu đóng vai exploratory tester giàu kinh nghiệm sẽ tự bật ra rủi ro hiệu năng (cron job full-scan khi subscriber base lớn) mà charter thủ công gần như không bao giờ nghĩ tới vì tester thường không đọc migration file.

Context Layer 3: Lịch sử bug pattern

Đây là "trí nhớ tổ chức" — thứ giúp AI không lặp lại charter đã từng cover, và biết tập trung vào những khu vực đội bạn từng bị "vấp" nhiều lần. Tổng hợp 3-5 bug điển hình liên quan (không cần đầy đủ, chỉ cần đủ để thấy pattern):

HISTORICAL BUG PATTERNS (billing/subscription module):
- BUG-1187: Timezone mismatch — cron job used UTC but displayed
  "resume date" to user in local time, causing 1-day-early charges
  for users in UTC+7 to UTC+9
- BUG-1340: Race condition — user clicked "Cancel" and "Pause"
  within 2 seconds via double-tab, resulting in subscription stuck
  in inconsistent state (both pause_end_date and cancelled_at set)
- BUG-1502: Refund flow didn't check pause state, allowed refund
  request during active pause, double-crediting the user

Context Layer 4: Biến thể Persona người dùng

Charter sinh ra không nên chỉ hình dung "một user chung". Nạp persona thật (dựa trên dữ liệu phân khúc nếu có) để AI tạo biến thể charter theo hành vi thực tế:

USER PERSONAS TO CONSIDER:
- "Power annual subscriber": has been on the platform 2+ years,
  likely has multiple payment methods on file, may have pending
  invoice disputes
- "New annual subscriber": signed up <30 days ago, may be inside
  a refund window
- "Family plan admin": manages 4 sub-accounts, pause action might
  need to cascade or might incorrectly cascade
- "Locale edge case user": billing address in a country with
  different tax/VAT rules on refund-adjacent actions

Full Context Prompt: Ghép tất cả lại

Đây là prompt đầy đủ, ghép bốn lớp context thành một yêu cầu duy nhất — đúng như cách tôi thường chạy trước một session thật với một tính năng có độ rủi ro billing cao:

You are a senior exploratory tester specializing in subscription and
billing systems. I'm going to give you four layers of context, then
ask you to generate a focused charter suite.

=== LAYER 1: FEATURE SPEC ===
As a subscriber, I want to pause my subscription for up to 3 months
so that I don't lose my account history when I travel.

Acceptance Criteria:
- Pause available only for annual plans, not monthly
- Max pause duration: 90 days, selectable in 30-day increments
- During pause: no billing occurs, content history retained,
  cannot access premium content
- User can resume early at any time
- Auto-resume triggers billing on day 91 if not manually resumed
- Pause option hidden if user has an active refund request

=== LAYER 2: CODE CHANGE ===
- Added `pause_end_date` column to subscriptions table
- Billing cron job (daily 02:00 UTC) checks pause_end_date before
  charging
- New "Pause subscription" button on Account page, calls
  PATCH /api/subscriptions/:id/pause
- Existing Cancel flow untouched but shares the subscriptions table
- No new index on pause_end_date

=== LAYER 3: HISTORICAL BUG PATTERNS ===
- BUG-1187: Timezone mismatch caused 1-day-early charges
- BUG-1340: Race condition between Cancel and Pause left
  inconsistent state
- BUG-1502: Refund flow didn't check pause state, caused
  double-crediting

=== LAYER 4: USER PERSONAS ===
- Power annual subscriber (multiple payment methods, dispute history)
- New annual subscriber (inside refund window)
- Family plan admin (4 sub-accounts)
- Locale edge case user (non-UTC timezone, different VAT rules)

=== TASK ===
Generate 5 test charters for this feature. For each charter, connect
the risk hypothesis explicitly back to at least one of the four
context layers above (cite which layer inspired it). Prioritize
charters that combine multiple layers (e.g. a persona interacting
with a specific code change) over charters based on a single layer.
Output as a table: Charter title | Mission | Risk hypothesis (+ source
layer) | Time-box | Priority.

Prompt này dài, nhưng đó là chủ đích — bạn đang trả tiền bằng token để đổi lấy charter chất lượng cao, tránh được hàng giờ session lan man. Trong thực tế tôi thường lưu prompt này thành template trong repo test, chỉ thay nội dung 4 layer mỗi lần dùng cho feature mới.

Đánh giá Output — Cái gì nên nhận, cái gì cần sửa

Không phải mọi charter AI sinh ra đều dùng được ngay. Ba tiêu chí lọc nhanh:

Tiêu chí Chấp nhận nếu... Cần sửa nếu...
Tính cụ thể Risk hypothesis trỏ tới một cơ chế cụ thể (cron job, race condition, cache) Risk hypothesis là câu chung như "may have edge cases"
Khả năng thực thi trong time-box Phạm vi vừa đủ một người test trong khung giờ đề xuất Charter thực chất cần 3-4 giờ nhưng ghi 30 phút
Liên kết context Có thể lần lại vì sao AI nghĩ ra rủi ro này (trỏ về layer nào) Rủi ro nghe hợp lý nhưng không có cơ sở nào trong context đưa vào — có thể AI "bịa" theo pattern chung của domain

Mẹo: Khi thấy một risk hypothesis "nghe hay nhưng vô căn cứ", đừng vội xóa — hỏi lại AI "why do you think this is a risk given the context I gave?". Nhiều lần câu trả lời tiết lộ một suy luận hợp lý mà bạn chưa nghĩ tới (ví dụ AI liên hệ với một pattern phổ biến trong hệ thống billing nói chung), và lúc đó nó lại trở thành charter đáng giá.

Điều chỉnh Charter do AI sinh ra cho Frontend, Backend, Mobile và CTV như thế nào?

Một charter sinh ra từ context chung thường mang giọng "web-centric" theo mặc định vì đó là dữ liệu huấn luyện phổ biến nhất. Nhiệm vụ của bạn là điều hướng lại theo đặc thù nền tảng đang test — nếu không, charter cho app mobile sẽ toàn nói về "click button" và "browser tab", vô nghĩa với ngữ cảnh gesture và lifecycle của mobile.

Điều chỉnh Charter cho Frontend (Web)

Với web, charter cần nhấn vào: tương tác đa tab/đa cửa sổ, trạng thái URL và deep-link, khả năng tương thích trình duyệt, responsive breakpoint, và hành vi khi mạng chập chờn (offline/slow 3G qua DevTools throttling). Prompt điều chỉnh:

Adapt the charter below for web frontend testing specifically. Add
explicit sub-missions for: browser back/forward navigation, page
refresh mid-flow, multiple tabs of the same session, and responsive
behavior at mobile-web breakpoint (375px) vs desktop.

[dán charter gốc]

Điều chỉnh Charter cho Backend / API

Backend charter nên bỏ hoàn toàn ngôn ngữ UI và chuyển sang: mã trạng thái HTTP, tính idempotent, race condition ở tầng dữ liệu, giới hạn rate-limit, và tính nhất quán khi có nhiều consumer cùng gọi API (ví dụ web và mobile cùng gọi một endpoint pause subscription cùng lúc).

Adapt the charter below for API-level exploratory testing (no UI).
Reframe the mission around: HTTP status code correctness, response
schema consistency across success/error cases, idempotency when the
same request is retried, and behavior under concurrent calls from
two different clients to the same resource.

[dán charter gốc]

Điều chỉnh Charter cho Mobile (iOS và Android)

Mobile mang theo một lớp rủi ro hoàn toàn khác: lifecycle app (background/foreground/kill), gián đoạn do notification hoặc cuộc gọi đến, quyền hệ điều hành (permission), và sự khác biệt giữa iOS/Android về gesture, back button (Android có nút back cứng, iOS không). Charter mobile tốt phải đặt câu hỏi "chuyện gì xảy ra nếu user rời app giữa flow rồi quay lại 10 phút sau".

Adapt the charter below for native mobile (iOS and Android). Add
sub-missions covering: app backgrounded mid-action then resumed,
OS-level permission prompts interrupting the flow, low-connectivity
or airplane-mode toggling mid-session, and platform-specific back
navigation (Android hardware back button vs iOS swipe-back gesture).
Call out any behavior likely to differ between the two platforms.

[dán charter gốc]

Điều chỉnh Charter cho CTV (Fire TV, Roku, Apple TV)

CTV (Connected TV) là nền tảng dễ bị bỏ quên nhất khi charter được sinh ra từ context chung, vì mô hình tương tác hoàn toàn khác: điều hướng bằng D-pad (lên/xuống/trái/phải + OK) chứ không có con trỏ hay chạm, focus management là rủi ro số một (phần tử nào đang được highlight, focus có "kẹt" hay "nhảy lung tung" không), và hiệu năng trên hardware yếu hơn nhiều so với điện thoại. Với CTV còn cần lưu ý remote control có hành vi khác nhau giữa các hãng (Fire TV remote, Roku remote, Siri Remote của Apple TV).

Adapt the charter below for Connected TV platforms (Fire TV, Roku,
Apple TV). Reframe all interactions in terms of D-pad navigation
(up/down/left/right/select) — remove any reference to clicking,
tapping, or hovering. Add sub-missions for: focus trap or lost focus
when a modal/dialog appears, focus behavior when returning from a
backgrounded state (user pressed Home then returned), and performance
degradation on lower-spec hardware. Note any platform-specific remote
control quirks (Siri Remote swipe vs D-pad clicks) that might cause
divergent behavior.

[dán charter gốc]

Mẹo: Đừng chỉ yêu cầu AI "adapt cho mobile" một cách chung — luôn chỉ rõ platform cụ thể (iOS 17 vs Android 14, Fire TV vs Apple TV). Mỗi hệ sinh thái có quirk riêng, và một charter "adapt cho mobile" mà không tách biệt sẽ trộn lẫn hành vi của cả hai, khiến tester bối rối khi nào áp dụng nhánh nào.

Bảng điều chỉnh Charter: Các chiều then chốt theo nền tảng

Chiều Frontend (Web) Backend / API Mobile (iOS/Android) CTV (Fire TV/Roku/Apple TV)
Trọng tâm khám phá Điều hướng URL, đa tab, responsive Status code, schema, idempotency Lifecycle app, permission, gesture Focus management, D-pad, hiệu năng phần cứng yếu
Công cụ hỗ trợ DevTools, Lighthouse, network throttling Postman/curl, contract test log, DB query trực tiếp Xcode/Android Studio logs, Charles Proxy, thiết bị thật Remote debugger của platform, log qua adb/SSH (nếu hỗ trợ)
Rủi ro đặc thù Cache trình duyệt, cross-browser CSS, back/forward cache Race condition đa client, rate limit, versioning API App bị kill bởi OS, mất kết nối giữa flow, khác biệt permission theo OS version Focus kẹt, remote control khác hãng, giới hạn RAM/CPU
Oracle điển hình So khớp UI với response API (consistency) So khớp response với schema/contract đã định nghĩa So khớp trạng thái trước/sau khi resume app So khớp phần tử đang có focus với kỳ vọng UX
Bẫy dễ bỏ sót khi test Test chỉ trên 1 trình duyệt, 1 độ phân giải Test chỉ happy path, bỏ qua concurrent request Test chỉ trên thiết bị mạng mạnh, quên bối cảnh nền Test chỉ bằng remote ảo trên emulator, không thử remote thật

Dùng Charter để dẫn dắt khám phá mà không bó buộc quá mức như thế nào?

Đây là câu hỏi triết lý cốt lõi của exploratory testing: charter phải đủ cụ thể để có định hướng, nhưng đủ mở để tester (hoặc AI agent hỗ trợ) có thể theo trực giác khi phát hiện điều bất ngờ. Một charter quá chi tiết biến session thành test case có checklist trá hình — mất hết giá trị của exploratory testing.

Sự căng thẳng: Tập trung và tính linh hoạt

James Bach có một nguyên tắc hay được trích: "charter là cái la bàn, không phải đường ray xe lửa". Nghĩa là charter chỉ hướng, chứ không quy định từng bước đi. Vấn đề là ranh giới giữa "đi lệch hướng có lý do" và "đi lang bang không kiểm soát" rất mong manh, đặc biệt khi bạn đang cộng tác với AI — vì AI, nếu không được nhắc, có xu hướng bám sát chữ nghĩa của charter một cách máy móc, hoặc ngược lại, drift quá xa khi thấy điều "thú vị" không liên quan mission.

Dùng AI để quyết định khi nào nên Pivot

Kỹ thuật hiệu quả nhất tôi áp dụng: mỗi khi phát hiện điều bất ngờ trong lúc test theo charter, dừng lại và hỏi AI đóng vai "session navigator" để quyết định có nên pivot (chuyển hướng) hay không, dựa trên mission gốc.

CURRENT CHARTER MISSION: Discover inconsistencies between displayed
discount tier and actual applied discount when cart quantity crosses
tier thresholds.

WHAT I JUST OBSERVED: While testing quantity changes, I noticed the
cart page takes 4-6 seconds to update the total after removing an
item — much slower than adding an item (under 1 second).

QUESTION: Should I pivot this session to investigate the performance
issue, log it as a side-note and continue the original mission, or
end the session early to open a dedicated charter for this?
Consider: is this observation related to the original risk hypothesis
(discount tier lag), or is it an unrelated finding? What's the
user-facing severity if this holds true broadly?

Trong ví dụ trên, một AI phân tích tốt sẽ chỉ ra: hiện tượng chậm khi remove có thể liên quan trực tiếp đến risk hypothesis gốc (discount tier tính toán server-side có thể là nguyên nhân của độ trễ này), nên nó gợi ý tiếp tục điều tra trong charter hiện tại thay vì mở charter mới — vì đây không phải "đi lệch hướng" mà là "đi sâu vào đúng hướng nhưng theo một triệu chứng khác".

Theo dõi độ phủ Charter theo thời gian thực

Một cách hay để giữ session không trôi quá xa là duy trì một "coverage log" ngắn ngay trong lúc test, và định kỳ (ví dụ mỗi 15 phút) nhờ AI đối chiếu lại với mission:

CHARTER MISSION: [dán mission]
TIME ELAPSED: 20 / 45 minutes
ACTIONS TAKEN SO FAR:
- Added 4 items (qty 4), checked no discount shown — correct
- Added 1 more (qty 5, hits threshold), discount appeared correctly
- Removed 1 item (qty 4, below threshold), discount label disappeared
  but subtotal still reflected discounted price for ~3 seconds
- Tried via quick-add widget on product page — same lag observed

Given the mission and time remaining, what risk areas from the
original hypothesis are still uncovered? Should I continue probing
the removal-lag issue or move to test the "saved-cart restore" path
mentioned in the risk hypothesis?

Cách làm này biến AI thành một "second brain" theo dõi tiến độ hộ bạn — điều mà khi test một mình, con người rất dễ quên vì bị cuốn theo một nhánh thú vị.

Mẹo: Viết log hành động bằng câu ngắn, thời gian thực (giống commit message), không phải tường thuật dài dòng ở cuối session. Log rời rạc nhưng liên tục giúp AI (và cả bạn khi đọc lại) tái dựng đúng trình tự phát hiện — điều rất quan trọng khi cần report lại root cause sau này.

Khi nào đóng Charter và khi nào tiếp tục

Ba tín hiệu nên đóng charter và mở charter mới (dù còn thời gian trong time-box):

  • Bạn đã trả lời được risk hypothesis chính (dù kết quả là "không tìm thấy vấn đề") — tiếp tục dò thêm trong cùng charter dễ dẫn tới lãng phí thời gian tìm bug ở khu vực đã đủ tự tin.
  • Phát hiện mới nằm ở một tầng kiến trúc hoàn toàn khác (ví dụ đang test UI nhưng phát hiện có thể là race condition ở database) — nên mở charter riêng có mission và người phù hợp (có thể cần backend engineer tham gia) thay vì cố gồng tiếp trong session hiện tại.
  • Thời gian còn lại không đủ để điều tra sâu bất kỳ hướng nào một cách có ý nghĩa — dừng sớm và ghi chú "carry-over" còn tốt hơn kéo dài session một cách hình thức.

Ngược lại, tín hiệu nên tiếp tục dù "có vẻ" đã đủ: khi phát hiện đầu tiên chỉ là triệu chứng bề mặt của một vấn đề sâu hơn (như ví dụ độ trễ discount ở trên) — lúc này pivot nhẹ trong cùng charter, không cần đóng.

Charter như một công cụ giao tiếp

Cuối cùng, đừng quên charter không chỉ dành cho người thực thi — nó là tài liệu giao tiếp với Product Manager, Dev Lead, và các tester khác. Một charter được AI sinh ra với risk hypothesis rõ ràng, có trích dẫn nguồn context, tự nhiên trở thành báo cáo có giá trị ngay cả khi session chưa chạy: nó cho thấy đội QA đã nghĩ về rủi ro gì trước khi bấm nút test, và giúp dev lead phản hồi sớm "risk này không đáng lo vì..." hoặc "đúng rồi, khu vực đó tụi mình cũng ngại".

Trong thực tế, tôi thường đưa charter suite (bảng 5-10 charter từ prompt layer đầy đủ ở trên) vào ngay comment của PR trước khi merge, như một dạng "test plan nhẹ" — không cần chờ đến lúc code freeze mới nghĩ tới việc test cái gì.

Mẹo: Khi chia sẻ charter cho stakeholder không phải QA, luôn bỏ phần "prompt kỹ thuật" và chỉ giữ 5 phần cấu trúc (charter, mission, time-box, risk hypothesis, out-of-scope) — trình bày dưới dạng bảng ngắn. Điều này giúp charter trở thành tài liệu ai đọc cũng hiểu, chứ không chỉ có QA hiểu.