Ở bài trước, chúng ta đã nhìn tổng quan Agentic QA Loop với 5-6 giai đoạn lặp lại. Bài này đi sâu vào Stage 2 — giai đoạn test planning. Đây là bước mà nhiều team QA làm rất hời hợt khi chuyển sang làm việc với AI: họ ném nguyên spec vào ChatGPT, gõ "viết test case cho tôi", rồi copy-paste kết quả vào Jira mà không kiểm tra lại. Kết quả là một plan trông "đủ dài" nhưng rủi ro thật của feature lại không được đánh giá đúng, và scope test thì lệch hẳn so với những gì code thực sự thay đổi.
Agentic test planning đúng nghĩa không phải là "hỏi AI viết test case". Nó là một quy trình có cấu trúc: nạp đúng ngữ cảnh (spec + diff + codebase), ép AI suy luận rủi ro một cách minh bạch, rồi con người review và approve trước khi bất kỳ automation hay manual testing nào bắt đầu. Đây là kỹ năng phân biệt một QA Lead biết dùng agent thành thạo với một người chỉ biết "prompt cho vui".
Làm sao để tạo ra một test plan hoàn chỉnh bằng cách kết hợp ngữ cảnh spec và code-change?
Sai lầm phổ biến nhất khi dùng AI để lập test plan là chỉ đưa một nửa ngữ cảnh. Đưa spec mà không đưa diff, AI sẽ test theo "ý định" chứ không biết dev thực sự code cái gì, code có sai lệch với spec hay không. Đưa diff mà không đưa spec, AI sẽ test theo "code làm gì" mà không biết đó có phải là điều business muốn hay không — nghĩa là bug logic nghiêm trọng nhất (code chạy đúng như code viết, nhưng sai với yêu cầu) sẽ lọt lưới hoàn toàn.
Nguyên tắc cốt lõi: test plan tốt phải được sinh ra từ giao điểm giữa "phải làm gì" (spec) và "đã làm gì" (diff). Đây gọi là dual-context input.
Chuẩn bị đầu vào Dual-Context (ngữ cảnh song song)
Trước khi viết prompt, bạn cần chuẩn bị hai nguồn ngữ cảnh riêng biệt, rõ ràng, và có thể verify được. Mình lấy ví dụ xuyên suốt bài này là feature "Checkout Address Validation" — một feature khá điển hình trong e-commerce, nơi rủi ro business rất cao (sai địa chỉ = mất đơn, mất hàng) nhưng lại thường bị QA đánh giá thấp vì "chỉ là validate form".
Step 1 — Capture the feature spec. Lấy nguyên văn User Story + Acceptance Criteria từ ticket, không paraphrase, không tóm tắt. AI suy luận tốt hơn nhiều khi đọc câu chữ gốc của Product/BA, vì đôi khi chính cách diễn đạt (ví dụ "must", "should", "if possible") đã ẩn chứa mức độ ưu tiên.
Feature: Checkout Address Validation
User Story:
As a customer checking out, I want the system to validate my shipping
address before I can proceed to payment, so that my order does not fail
delivery due to an invalid or incomplete address.
Acceptance Criteria:
AC1. System must validate postal code format based on the selected country
(US: 5-digit ZIP, UK: alphanumeric postcode, VN: no strict format,
accept freeform).
AC2. If postal code format is invalid, block "Continue to Payment" and show
inline error under the postal code field.
AC3. System calls an address-autocomplete API (Google Places) when user
types 5+ characters in the street address field.
AC4. If the autocomplete API times out or errors, user must still be able
to manually type and submit the address (graceful degradation).
AC5. Address validation must NOT block checkout for countries not covered
by the postal code rule set (fallback: accept any non-empty value).
AC6. Validated address must be saved to the order record before navigating
to the payment step.
Step 2 — Capture the code change (diff). Không đưa toàn bộ file, đưa diff thật (git diff giữa base branch và feature branch) — vì diff cho AI biết chính xác điều gì thay đổi, cái gì là logic mới, cái gì là logic cũ không đổi (nên rủi ro regression thấp hơn). Nếu PR quá lớn, hãy giới hạn diff vào các file liên quan trực tiếp đến feature, loại bỏ file lockfile, snapshot test, file gen tự động.
diff --git a/src/checkout/validateAddress.ts b/src/checkout/validateAddress.ts
@@ -12,8 +12,22 @@ export function validateAddress(address: Address): ValidationResult {
- if (!address.postalCode) {
- return { valid: false, error: 'Postal code required' };
- }
+ const rule = POSTAL_CODE_RULES[address.country];
+ if (!rule) {
+ // No rule defined for this country -> accept any non-empty value
+ return address.postalCode?.trim()
+ ? { valid: true }
+ : { valid: false, error: 'Postal code required' };
+ }
+ if (!rule.pattern.test(address.postalCode)) {
+ return { valid: false, error: rule.errorMessage };
+ }
return { valid: true };
}
diff --git a/src/checkout/AddressForm.tsx b/src/checkout/AddressForm.tsx
@@ -40,6 +40,18 @@ export function AddressForm() {
+ const { suggestions, loading, error } = useAddressAutocomplete(street);
+ // fallback: if autocomplete errors out, hide suggestion list but keep
+ // the input editable
+ useEffect(() => {
+ if (error) setAutocompleteAvailable(false);
+ }, [error]);
Step 3 — Verify both exist and are readable. Bước này nghe đơn giản nhưng là nơi rất nhiều người bỏ qua rồi trả giá sau: mở lại spec xem ticket còn "Draft" hay đã "Ready for Dev" chưa, xem diff có phải branch mới nhất (đã rebase với main) chưa, và xem AI agent (Claude Code, Cursor…) có đang chạy trong đúng repo, đúng branch checkout không. Nếu bạn đưa diff cũ, AI sẽ lập plan cho code đã bị sửa lại — plan trông rất "chuẩn" nhưng thực chất đang test một phiên bản không tồn tại.
Mẹo: Đừng để AI tự đi lấy diff bằng cách chạy git diff trong agent shell nếu bạn không kiểm soát được branch nào đang active — agent có thể vô tình diff nhầm base branch (develop thay vì main) và cho ra danh sách "thay đổi" gồm cả code của người khác chưa merge. Luôn tự chạy git diff main...feature/checkout-address-validation và dán kết quả tường minh vào prompt, hoặc chỉ định rõ range commit trong instruction.
Prompt Agentic Test Planning hoàn chỉnh
Đây là phần khung xương của kỹ thuật này: một prompt có cấu trúc 5 phần (ROLE, SPEC CONTEXT, CODE CHANGE CONTEXT, CODEBASE CONTEXT, YOUR TASK), tách bạch rõ ràng ngữ cảnh với nhiệm vụ, giúp AI không nhầm lẫn "đây là dữ kiện" với "đây là việc cần làm".
You are a senior QA engineer performing test planning for a feature
before test execution begins. You reason like someone who has shipped
production e-commerce checkout flows and has seen address-related bugs
cause real order failures.
<paste the full User Story + Acceptance Criteria from Step 1 here>
<paste the full git diff from Step 2 here>
- Frontend: React + TypeScript, form state managed with React Hook Form.
- validateAddress() is called both client-side (on blur) and server-side
(in POST /api/checkout/address) before order creation — treat both call
sites as in scope.
- POSTAL_CODE_RULES is a static map in src/checkout/postalCodeRules.ts,
currently covers US, UK, CA, AU, DE. VN and 190+ other countries fall
into the "no rule" branch.
- useAddressAutocomplete wraps a 3rd-party Google Places API call with a
2-second timeout, defined in src/checkout/useAddressAutocomplete.ts.
- Known historical defect: BUG-4821 (3 months ago) — postal code
validation for CA addresses accepted invalid format due to a regex typo,
reached production for 2 days before hotfix.
Based ONLY on the context above, produce a test plan with these sections:
1. Feature Summary (from a QA perspective — what could go wrong, not just
what the feature does).
2. Spec-Implementation Alignment Check — flag ANY acceptance criterion
that the diff does not appear to implement, or any code behavior not
covered by an acceptance criterion.
3. Risk Assessment — table of risk areas with Likelihood, Impact, Priority,
and explicit reasoning citing the diff or spec.
4. Test Scope — explicit in-scope and out-of-scope boundaries.
5. Test Scenarios (Risk-Ordered) — grouped by priority, highest risk first.
6. Coverage Goals — what "done" looks like for this test cycle.
7. Entry and Exit Criteria for this test cycle.
Do not invent acceptance criteria that are not stated. If information is
missing to assess a risk, say so explicitly instead of guessing.
Ba chi tiết đáng chú ý trong prompt trên, vì chúng quyết định chất lượng output hơn 90% các yếu tố khác:
- "Do not invent acceptance criteria that are not stated" — chặn thói quen "hallucinate" của LLM, khi nó tự bổ sung tiêu chí nghe hợp lý nhưng business chưa từng yêu cầu, khiến plan bị phình to sai hướng.
- Codebase Context có kèm lịch sử bug (BUG-4821) — đây chính là "tri thức ngầm" (tacit knowledge) mà QA senior mang theo trong đầu nhưng ít khi viết vào ticket. Đưa nó vào prompt là cách "cấy" kinh nghiệm thật vào quá trình suy luận của AI.
- "If information is missing... say so explicitly" — đây là câu quan trọng nhất trong toàn prompt. Nó buộc AI thừa nhận giới hạn thay vì lấp đầy khoảng trống bằng suy đoán trông có vẻ tự tin.
Ví dụ output: phần Risk Assessment
Với prompt trên, một AI agent được cấu hình tốt sẽ trả ra một bảng risk assessment tương tự thế này (rút gọn để minh họa):
| Risk Area | Likelihood | Impact | Priority | Reasoning |
|-------------------------------------|-----------|--------|----------|-----------|
| Postal code regex incorrect per | Medium | High | P0 | Diff introduces new regex-based rules
| country (esp. countries similar to | | | | per country. Historical defect BUG-4821
| CA regex bug history) | | | | occurred in exactly this code path.
|-------------------------------------|-----------|--------|----------|-----------|
| Countries with no rule defined | High | High | P0 | AC5 explicitly requires fallback for
| (fallback path) silently block | | | | uncovered countries; diff's fallback
| checkout instead of accepting | | | | logic (`rule ? ... : ...`) is new and
| any value | | | | untested — a bug here blocks checkout
| | | | | for 190+ countries, not just 5.
|-------------------------------------|-----------|--------|----------|-----------|
| Autocomplete API failure not | Medium | Medium | P1 | AC4 requires graceful degradation.
| degrading gracefully | | | | Diff sets autocompleteAvailable via a
| | | | | useEffect on `error` — race condition
| | | | | possible if API errors after timeout
| | | | | already fired.
|-------------------------------------|-----------|--------|----------|-----------|
| Server-side validation diverges | Low | High | P1 | Spec does not clarify if server-side
| from client-side validation | | | | validateAddress() call must use the
| | | | | same rule set — flagged in Section 2
| | | | | (Spec-Implementation Alignment Check).
Chú ý: rủi ro cao nhất theo AI không phải là điều "trông nguy hiểm nhất" (regex quốc gia), mà là fallback path — cái mà nếu chỉ đọc spec lướt qua, con người thường đánh giá thấp vì nó là "trường hợp không có rule, dễ mà, cứ accept hết". Đây chính là giá trị thật của agentic test planning: AI không mệt, không chủ quan, và nó nối được đầu mối giữa "diff mới" và "historical defect" — một việc con người hay quên làm khi đang gấp deadline.
Mẹo: Luôn yêu cầu AI trích dẫn cụ thể dòng diff hoặc câu AC làm căn cứ cho mỗi risk, đừng chấp nhận risk assessment "không có nguồn". Nếu một dòng risk không trích được bằng chứng cụ thể, đó thường là dấu hiệu AI đang suy diễn chung chung (generic testing knowledge) chứ không thực sự phân tích ngữ cảnh bạn đưa vào — hỏi lại "which line of the diff supports this?" để lọc ra risk giả.
AI tạo ra risk prioritization, scope, và coverage goals trong một lượt như thế nào?
Phần trên cho thấy kết quả. Phần này giải thích cơ chế bên trong — AI dựa vào đâu để xếp hạng rủi ro, vẽ ranh giới scope, và đặt mục tiêu coverage — để bạn biết khi nào nên tin, khi nào nên nghi ngờ và hỏi lại.
Cách AI suy ra mức độ ưu tiên rủi ro (Risk Priority)
Khi bạn cung cấp đủ dual-context, AI thường suy luận risk priority dựa trên tổ hợp các tín hiệu sau (nó không nói ra tường minh trừ khi bạn ép, nhưng đây là pattern quan sát được qua nhiều lần thử nghiệm thực tế):
- Kích thước và độ phức tạp của thay đổi trong diff — hàm bị viết lại hoàn toàn (như
validateAddress) rủi ro cao hơn hàm chỉ đổi 1 dòng. - Số lượng nhánh logic mới (branching) — mỗi
if/elsemới thêm là một đường thi hành chưa có test, coverage cũ không còn bảo vệ được. - Business criticality từ spec — câu chữ như "must", "block", ràng buộc cứng trong AC thường được AI gán impact cao hơn "should", "nice to have".
- Lịch sử defect — nếu bạn đưa vào codebase context, đây là tín hiệu mạnh nhất, vì nó là dữ liệu thật chứ không phải suy luận.
- Phạm vi ảnh hưởng (blast radius) — hàm được gọi ở nhiều nơi (client + server, như ví dụ trên) rủi ro cao hơn hàm chỉ dùng ở 1 nơi.
- Phụ thuộc bên ngoài (external dependency) — gọi API bên thứ ba (Google Places) luôn được gắn rủi ro cao hơn logic thuần nội bộ, vì AI "biết" (từ tri thức tổng quát) rằng external API là nguồn lỗi phổ biến: timeout, rate limit, thay đổi contract.
Sai lầm phổ biến ở đây: nhiều QA chỉ đưa spec, không đưa diff, rồi thắc mắc vì sao AI xếp risk chung chung, kiểu "cần test kỹ validation" mà không chỉ rõ path nào. Không có diff, AI không có cơ sở để phân biệt "logic cũ, ổn định" với "logic mới, chưa test" — nó chỉ có thể suy luận risk ở mức ý tưởng nghiệp vụ, tức là hời hợt.
Prompt để AI giải thích rõ lý do đánh giá rủi ro
Muốn kiểm soát chất lượng risk assessment, đừng chỉ hỏi "what are the risks", mà ép AI trình bày lý do theo một khung cố định. Thêm đoạn này vào Task section:
For each risk row, you MUST include:
- The specific line(s) of the diff or clause of the spec that justifies it
(quote it directly).
- Why the likelihood rating was chosen (not just "medium" — explain).
- What the worst realistic user-facing consequence is if this risk is not
tested (not the theoretical worst case, the REALISTIC one).
If two risks seem to have similar severity, explicitly compare them and
justify which one ranks higher.
Kỹ thuật "buộc so sánh cặp" (pairwise comparison) ở câu cuối rất hiệu quả để chống hiện tượng AI liệt kê 8 risk đều là "P0" — một dạng lạm phát mức độ ưu tiên khiến plan mất khả năng định hướng test effort.
Mẹo: Nếu bạn nghi ngờ AI đang "chấm điểm rủi ro theo cảm tính", hãy hỏi ngược: "Rank these risks assuming we only have time to test 2 out of 5 — which 2, and why." Câu trả lời buộc AI bộc lộ rõ logic ưu tiên thật, thường khác hẳn (và đáng tin hơn) so với bảng risk ban đầu — vì nó loại bỏ được các risk được gắn P0 chỉ vì "nghe có vẻ quan trọng".
Cách AI xác định Scope (phạm vi test)
Scope tốt cần cả in-scope và out-of-scope — thiếu phần out-of-scope là lỗi rất thường gặp khi tự viết test plan, và AI cũng mắc lỗi này nếu bạn không nhắc. Với ví dụ Checkout Address Validation, một scope hợp lý AI thường đưa ra là:
- In-scope: postal code validation cho 5 quốc gia có rule, fallback cho quốc gia không có rule, autocomplete happy path + timeout/error path, đồng bộ giữa client-side và server-side validation, lưu địa chỉ đã validate vào order record.
- Out-of-scope (cần nêu rõ lý do): UI/UX của autocomplete dropdown (chưa đổi trong diff), payment step sau khi checkout (không nằm trong diff), địa chỉ đã lưu từ trước (address book — không có trong AC).
Cơ chế AI dùng để vẽ ranh giới này chính là truy vết từ diff ra ngoài (tương tự static dependency analysis con người làm bằng mắt, nhưng AI làm nhanh và ít bỏ sót hơn nếu codebase context đủ chi tiết): file nào bị đổi → module nào import/gọi file đó → luồng nghiệp vụ nào chạy qua module đó. Nếu bạn không cung cấp thông tin cấu trúc codebase (ai gọi validateAddress, ở đâu), AI sẽ chỉ scope theo tên hàm/file bị đổi, dễ bỏ sót các điểm gọi gián tiếp — đây là lý do phần Codebase Context trong prompt không thể bỏ qua.
Cách AI thiết lập Coverage Goals (mục tiêu độ phủ)
Coverage goal khác risk assessment: risk assessment nói "chỗ nào nguy hiểm", coverage goal nói "làm sao biết mình đã test đủ". Một pattern coverage goal tốt AI thường tạo ra khi được yêu cầu đúng cách:
Coverage Goals:
- 100% of Acceptance Criteria (AC1–AC6) mapped to at least one test
scenario — no AC left without a corresponding test.
- Every branch in the new POSTAL_CODE_RULES lookup logic exercised:
rule exists + valid, rule exists + invalid, rule does not exist +
empty value, rule does not exist + non-empty value.
- Autocomplete: success path, timeout path (simulate >2s delay), and
API error path (4xx/5xx) each have at least one scenario.
- Client-side and server-side validation each tested independently AND
tested for consistency (same input -> same accept/reject decision).
Điểm mấu chốt: coverage goal tốt luôn truy vết ngược lại được AC hoặc branch cụ thể trong diff — nếu coverage goal của bạn (hoặc của AI) chỉ là câu chung như "test kỹ các trường hợp edge case", nó vô dụng vì không đo lường được. Traceability (khả năng lần vết) là tiêu chí quan trọng nhất khi bạn review coverage goal ở phần sau.
Mẹo: Khi AI đề ra coverage goal, luôn hỏi thêm "Which of these coverage goals, if unmet, would you personally block release for?" — câu trả lời tách goal ra 2 nhóm: goal thực sự là release-blocker và goal chỉ là "nice to have". Nhiều team AQA (Agentic QA) treo cổ mình vì coi mọi coverage goal AI đưa ra đều ngang hàng, dẫn đến vòng review approval bị kéo dài không cần thiết.
Làm sao để review và approve một test plan do AI tạo trước khi thực thi?
Đây là bước quan trọng nhất và dễ bị bỏ qua nhất. Rất nhiều case study thất bại về "AI testing" thực chất không phải vì AI sinh plan tệ, mà vì không có ai review trước khi automation bắt đầu chạy theo plan đó — lãng phí hàng giờ compute (thời gian máy chạy) và rất nhiều công sức để tự động hóa những test case sai hướng.
Nguyên tắc: test plan do AI sinh ra là draft, không phải deliverable. Nó chỉ trở thành deliverable sau khi có approval gate của người có thẩm quyền (thường là QA Lead hoặc người sở hữu feature).
Checklist review 5 điểm
Khi review một plan do AI tạo, dùng 5 tiêu chí sau — thiết kế để bắt đúng những lỗi đặc thù của AI-generated content (khác với lỗi khi review plan do người viết):
- Traceability — mọi risk/scenario có trích được nguồn (spec clause hoặc diff line) không? Nếu không, khả năng cao đó là suy diễn chung, không đặc thù cho feature này.
- Không có "AC ma" — AI có tự bịa thêm acceptance criterion nào không có trong spec gốc không? (Kiểm tra ngược lại với bản spec gốc, không phải bản AI tóm tắt).
- Không thiếu code path nào trong diff — mở lại diff, kiểm từng hunk (đoạn thay đổi), xem có nhánh logic nào chưa xuất hiện trong bất kỳ test scenario nào không.
- Risk ranking có hợp lý với domain knowledge thật của bạn không? Đây là chỗ QA senior phải dùng kinh nghiệm: nếu bạn biết team hay bug ở đâu (như BUG-4821) nhưng AI không xếp nó P0, có thể do bạn quên đưa thông tin đó vào context — không phải do AI "sai", mà do bạn "thiếu context".
- Entry/Exit criteria có khả thi với timeline sprint thực tế không? AI không biết team có 2 ngày hay 2 tuần trừ khi bạn nói — nó thường đề ra coverage goal lý tưởng, không phải coverage goal khả thi.
Sai lầm thường gặp nhất ở bước này là "blindly trust the ranking" — tin tưởng tuyệt đối thứ tự P0/P1/P2 mà AI đưa ra chỉ vì nó trình bày gọn gàng, có bảng, có số liệu, trông rất "khoa học". Một bảng đẹp không đồng nghĩa với suy luận đúng. Luôn hỏi ngược ít nhất 1-2 dòng risk ở giữa bảng (không phải dòng đầu, không phải dòng cuối — vì AI có xu hướng đầu tư nhiều "chất lượng lý luận" hơn cho các dòng đầu/cuối).
Quy trình Approval Gate
Approval gate không cần công cụ phức tạp, quan trọng là có một điểm chốt tường minh trước khi chuyển sang giai đoạn viết test case / automation. Một quy trình thực tế mình dùng ở team:
- Test plan (bản AI sinh + note review của QA) được đính kèm vào ticket dưới dạng comment hoặc file
test-plan-v1.mdtrong PR. - QA Lead (hoặc peer QA nếu không có Lead) review theo checklist 5 điểm trên, để lại comment "Approved" hoặc "Changes requested" — giống hệt quy trình code review, chỉ khác đối tượng review là test plan.
- Nếu "Changes requested", quay lại prompt, bổ sung ngữ cảnh thiếu (thường là thiếu domain knowledge hoặc thiếu 1 phần diff), yêu cầu AI regenerate — không tự tay sửa từng dòng plan, vì lần sau lại phải sửa tiếp khi diff đổi.
- Chỉ sau "Approved", plan mới được dùng làm input cho Stage 3 (sinh test case / automation) của Agentic QA Loop.
Mẹo: Đừng approve "cả gói" (toàn bộ plan một lần) khi plan có nhiều risk P0. Approve theo từng nhóm risk — approve trước phần P0 để automation/manual testing có thể bắt đầu ngay trên phần rủi ro cao nhất, trong khi bạn tiếp tục review phần P1/P2. Cách này giảm đáng kể thời gian chờ giữa "planning" và "bắt đầu test thật" mà không đánh đổi chất lượng review.
Làm sao để điều chỉnh test plan do AI tạo khi feature thay đổi giữa sprint?
Test plan không phải văn bản tĩnh. Trong thực tế agile, spec đổi giữa sprint là chuyện thường ngày — và một plan không theo kịp thay đổi sẽ nhanh chóng trở thành tài liệu "trông có vẻ đúng" nhưng thực chất đang dẫn dắt test effort sai hướng.
Nhận biết khi nào plan cần được cập nhật
Không phải mọi thay đổi nhỏ đều cần regenerate plan — regenerate quá thường xuyên gây mệt review, quá hiếm thì plan lỗi thời. Các tín hiệu đáng để trigger update:
- Có comment "Spec Change" mới trên ticket, thay đổi hoặc thêm Acceptance Criteria.
- Diff mới push lên thêm/đổi nhánh logic không nằm trong diff ban đầu đã lập plan.
- QA hoặc dev phát hiện edge case thật trong lúc test thăm dò (exploratory testing) mà plan chưa cover — đây là dấu hiệu plan có gap, không chỉ là "thêm 1 test case lẻ".
- Stakeholder yêu cầu bổ sung phạm vi (ví dụ: "thêm luôn hỗ trợ postal code cho Singapore") giữa sprint.
Cập nhật plan: Delta Regeneration (tái tạo phần thay đổi)
Sai lầm phổ biến: regenerate lại toàn bộ plan từ đầu mỗi khi có thay đổi nhỏ — tốn token, tốn thời gian review lại từ đầu, và dễ làm mất các quyết định approval đã chốt trước đó (những phần không đổi mà vẫn bị AI viết lại khác đi do random trong sinh văn bản). Cách hiệu quả hơn là delta regeneration — chỉ đưa phần thay đổi (delta) làm ngữ cảnh mới, yêu cầu AI regenerate đúng những section bị ảnh hưởng.
Ví dụ, giả sử 2 tuần sau, PM comment thêm:
Spec Change (2024-01-15):
AC7 (NEW). System must support Singapore postal codes (6-digit numeric,
no letters) — added per regional expansion requirement from Sales team.
This was NOT in the original scope when this feature was planned.
Prompt delta regeneration:
<paste the full approved v1 plan>
<paste "Spec Change (2024-01-15)" above>
<paste new diff hunk adding SG to POSTAL_CODE_RULES, if code already exists>
This is an incremental update to an already-approved plan, not a full
rewrite. Identify ONLY the sections that must change because of the delta
above (likely: Risk Assessment, Test Scope, Test Scenarios, Coverage
Goals). Leave all other sections and their wording UNCHANGED. Output:
(a) a list of which sections changed and why,
(b) the full updated text of ONLY those sections.
Kỹ thuật quan trọng nhất trong prompt trên là "leave all other sections unchanged" — nó giữ tính ổn định cho phần đã được approve, giúp reviewer chỉ cần review đúng phần delta thay vì đọc lại toàn bộ plan mỗi lần có thay đổi nhỏ, giống hệt tinh thần "review incremental diff" trong code review.
Quản lý phiên bản plan (Plan Versions)
Khi plan được regenerate nhiều lần trong 1 sprint, cần versioning rõ ràng để không ai lẫn giữa bản đang chạy test và bản đã lỗi thời. Cách đơn giản và đủ dùng cho hầu hết team:
- Đặt tên file/section theo version:
test-plan-v1.md,test-plan-v2-delta-sg-postal-code.md, lưu cùng thư mục với ticket hoặc trong repo cạnh code (nếu team đã quen infra-as-code cho test artifact). - Giữ một changelog table ở đầu file plan, ghi ngắn gọn từng lần thay đổi:
| Version | Date | Trigger | Sections Changed | Approved By |
|---------|-----------|-----------------------------------|----------------------------|-------------|
| v1 | 2024-01-08 | Initial plan from spec + diff | All | qa-lead |
| v2 | 2024-01-15 | Spec Change: AC7 (SG postal code) | Risk, Scope, Scenarios | qa-lead |
- Không xóa version cũ. Giữ lại để trả lời được câu hỏi "tại sao lúc đó mình không test case này" nếu sau này có bug lọt ra production — đây chính là audit trail (dấu vết thay đổi) giúp retro sau sprint có dữ liệu thật, không phải nhớ lại theo cảm tính.
Triage giữa sprint cho các scope bổ sung muộn
Không phải mọi yêu cầu bổ sung muộn đều nên vào ngay plan hiện tại. Khi có scope mới xuất hiện giữa sprint (như case Singapore postal code ở trên), cần một bước triage nhanh trước khi quyết định regenerate:
A new scope item has been requested mid-sprint: "<paste request>".
Sprint ends in <N> days. Current plan is already v<X>, status: <in
progress / test execution started>.
Assess:
1. Can this be added to the CURRENT plan without invalidating already-
executed test results? (Yes/No + why)
2. What is the realistic regression risk if this ships WITHOUT being
added to the current cycle's test scope?
3. Recommend: add to current plan now / defer to next sprint's plan /
needs a hotfix-style expedited micro-plan.
Câu hỏi (2) là câu quan trọng nhất — nó buộc bạn (và AI) định lượng cái giá của việc không test ngay, thay vì mặc định "cứ thêm vào cho chắc" (làm phình effort không cần thiết) hoặc mặc định "để sau" (rủi ro bug lọt ra production). Phần lớn trường hợp thực tế, câu trả lời đúng là: nếu scope mới độc lập với code đã test (ví dụ chỉ thêm 1 entry vào POSTAL_CODE_RULES, không đụng logic chung), có thể thêm vào current plan dưới dạng delta nhỏ mà không cần re-test lại toàn bộ; nếu scope mới đụng vào core logic đã test xong, nên defer để tránh phải test lại từ đầu ngay sát deadline.
Mẹo: Giữ một "mini delta-plan" riêng cho các yêu cầu phát sinh gấp trong ngày cuối sprint, đừng cố nhét nó vào plan chính đang chạy — việc này giúp bạn approve nhanh một phạm vi nhỏ, độc lập, mà không phải mở lại toàn bộ approval gate của plan chính đã chốt từ đầu sprint. Đây cũng là cách thực tế nhất để plan chính không bị "bơm phồng" theo thời gian, giữ được tính tường minh (traceable) mà nó cần có ngay từ đầu.
Tóm lại, agentic test planning không thay thế tư duy risk-based testing của QA — nó là một cách nhân bản và làm minh bạch hóa tư duy đó, với điều kiện bạn cung cấp đủ ngữ cảnh thật (spec + diff + codebase knowledge) và giữ vững kỷ luật review/approve trước khi tin tưởng bất kỳ plan nào. Ở bài tiếp theo, chúng ta sẽ dùng chính plan đã approve này làm input để AI sinh manual test case chi tiết — Stage 3 của Agentic QA Loop.