·

Tiếng Việt: Evaluating acceptance criteria for testability

Evaluating acceptance criteria for testability

Acceptance criteria (AC — tiêu chí chấp nhận) là hợp đồng ngầm giữa Product Owner, Dev và QA về việc "xong" nghĩa là gì. Nhưng trong thực tế, phần lớn AC được viết vội trong buổi refinement, mang tính mô tả hành vi chung chứ không phải điều kiện kiểm tra được. Hệ quả: QA tốn hàng giờ đoán ý, viết test case dựa trên giả định, rồi phát hiện ra scope thật sự khác hoàn toàn khi PR đã merge.

Bài này tập trung vào một kỹ năng cụ thể: dùng AI như một "máy audit" AC trước khi sprint bắt đầu — phát hiện câu chữ mơ hồ, liệt kê edge case còn thiếu, và biến AC yếu thành điều kiện test được mà không cần chờ một buổi họp mới. Đây là kỹ năng bắt buộc với QA senior, vì nó dịch chuyển vai trò của bạn từ "người viết test case sau cùng" thành "người gác cổng chất lượng requirement" — nơi giá trị phòng ngừa lỗi cao nhất.

Điều Gì Khiến Acceptance Criteria Testable — Precision, Observability, Completeness?

Một AC "nghe có lý" và một AC "test được" là hai thứ khác nhau. Câu "Hệ thống phải xử lý lỗi một cách hợp lý" nghe hoàn toàn hợp lý trong buổi họp, nhưng không ai — kể cả người viết ra nó — có thể trả lời được câu hỏi "test case nào sẽ pass, test case nào sẽ fail?". Để AC testable, nó phải đáp ứng đồng thời ba thuộc tính, thiếu một là QA sẽ phải tự bịa ra giả định.

Ba Trụ Cột Của Acceptance Criteria Testable

Precision (độ chính xác): AC phải chỉ rõ giá trị, ngưỡng, hoặc quy tắc cụ thể — không dùng tính từ mơ hồ như "nhanh", "hợp lý", "thân thiện", "đầy đủ". Ví dụ "Hệ thống phản hồi nhanh" không precision. "Hệ thống phản hồi trong vòng 2 giây với 95th percentile khi tải 100 request đồng thời" thì precision, vì có số, có ngưỡng, có điều kiện đo.

Observability (khả năng quan sát): Kết quả của AC phải quan sát được từ bên ngoài hệ thống — qua UI, API response, log, hoặc database state — mà không cần biết chi tiết implementation. Một AC như "Component phải được tối ưu về performance" không observable vì "tối ưu" không map tới một tín hiệu đo được cụ thể. Ngược lại, "API trả về status 429 và header Retry-After khi vượt rate limit 100 req/phút" là observable — QA có thể gửi request và kiểm tra response.

Completeness (tính đầy đủ): AC phải bao trùm cả happy path, error path, và boundary — không chỉ mô tả trường hợp lý tưởng. Một AC chỉ nói "User đăng nhập thành công với email và password hợp lệ" mà bỏ qua trường hợp sai password, account bị khóa, hay session hết hạn là AC không complete — nó chỉ mô tả 1/n số nhánh nghiệp vụ thực tế.

Ba pillar này không độc lập — một AC có thể precision nhưng vẫn thiếu completeness (rất precision về happy path nhưng không đề cập lỗi). QA cần đánh giá đủ cả ba trước khi bắt tay viết test case, vì viết test case dựa trên AC thiếu một trong ba pillar đồng nghĩa với việc bạn đang tự thiết kế requirement thay cho Product Owner — rủi ro sai lệch scope rất cao.

Bộ Lọc SMART Cho AC

Mượn khung SMART (thường dùng cho mục tiêu công việc) và áp cho AC là một cách filter nhanh, dễ nhớ, áp dụng được ngay trong buổi refinement:

Chữ Ý nghĩa khi áp cho AC Câu hỏi kiểm tra
Specific AC nói rõ đối tượng, hành động, kết quả — không mơ hồ AC này có thể hiểu theo 2 cách khác nhau không?
Measurable Kết quả AC có thể đo bằng giá trị/boolean rõ ràng Làm sao tôi biết AC này pass hay fail?
Achievable AC khả thi trong phạm vi hệ thống, không mâu thuẫn với AC khác AC này có xung đột với constraint kỹ thuật đã biết không?
Relevant AC gắn với giá trị nghiệp vụ thực, không phải chi tiết implementation AC này có đang mô tả "cách làm" thay vì "kết quả cần đạt"?
Testable Có thể viết ít nhất 1 test case rõ ràng từ AC này Tôi có thể viết test case ngay bây giờ, không cần hỏi lại không?

Khi review AC trong backlog, chỉ cần lướt qua 5 câu hỏi này cho mỗi dòng AC. Nếu một AC "rớt" từ 2 chữ trở lên trong SMART, đó là tín hiệu để đưa ra concern ngay trong buổi refinement, thay vì chờ đến khi bắt đầu viết test case.

Mẹo: Đừng review AC một mình trong đầu — in ra hoặc paste AC vào một file riêng, đánh dấu (highlight) từng từ mơ hồ như "nhanh", "phù hợp", "một số", "khi cần". Những từ này gần như luôn là dấu hiệu AC thiếu precision. Sau vài sprint làm quen, bạn sẽ nhận diện được các "red flag word" đặc trưng của team mình để việc scan diễn ra trong vài phút.

Làm Sao Dùng AI Để Audit Acceptance Criteria Về Ambiguity Và Missing Edge Case?

Đọc AC bằng mắt người rất dễ bỏ sót vì não bộ tự động "điền vào chỗ trống" theo ngữ cảnh quen thuộc. AI không có thiên kiến ngữ cảnh đó (hoặc ít hơn), và có thể được prompt để soi từng câu theo checklist cố định — nhanh hơn, nhất quán hơn, và không bị mệt sau AC thứ 20 trong ngày.

Prompt Audit Testability Cho AC

Đây là prompt khung có thể copy-paste dùng ngay, dán trực tiếp AC từ Jira/ticket vào:

Bạn là Senior QA Engineer đang review Acceptance Criteria (AC) trước khi sprint planning.

Nhiệm vụ: Audit đoạn AC dưới đây theo 3 tiêu chí Precision, Observability, Completeness.

AC cần audit:
"""
{dán AC gốc vào đây}
"""

Với mỗi câu/dòng AC, trả về theo format:
1. Câu AC gốc
2. Vấn đề phát hiện (nếu có): loại vấn đề (Ambiguous / Not Observable / Missing Edge Case / Conflicting), giải thích ngắn tại sao
3. Câu hỏi clarify cần hỏi Product Owner (nếu cần)
4. Đề xuất viết lại AC theo hướng testable hơn (Given-When-Then nếu phù hợp)

Cuối cùng, tổng hợp:
- Danh sách edge case KHÔNG được đề cập trong AC nhưng có khả năng xảy ra trong nghiệp vụ này (dựa trên loại feature)
- Đánh giá tổng quan: AC này đã đủ để bắt đầu viết test case chưa? (Đủ / Cần clarify / Chưa đủ)

Không tự suy diễn business rule không có trong AC — chỉ đánh dấu là "cần clarify" khi thiếu thông tin.

Chi tiết quan trọng nằm ở dòng cuối: "Không tự suy diễn business rule không có trong AC". Nếu bỏ dòng này, LLM có xu hướng tự "sáng tác" ra business rule hợp lý để lấp khoảng trống — hành vi hữu ích khi brainstorm nhưng nguy hiểm khi audit, vì QA sẽ tưởng rule đó có thật và dựa vào nó viết test case sai.

Nhận Diện Pattern Ngôn Ngữ Mơ Hồ

Ambiguity trong AC thường rơi vào vài nhóm pattern lặp lại. Việc dạy AI (qua prompt) nhận diện đúng các pattern này giúp audit chính xác hơn thay vì chỉ nói chung "câu này mơ hồ":

  • Tính từ định lượng mơ hồ: "nhanh", "chậm", "nhiều", "một số", "phù hợp", "hợp lý", "thân thiện". Không có số, không có ngưỡng.
  • Đại từ/danh từ chỉ đối tượng không rõ: "hệ thống sẽ xử lý" — xử lý ở tầng nào? UI hiển thị message, hay backend log, hay cả hai?
  • Điều kiện ẩn (implicit condition): "Khi user submit form, dữ liệu được lưu" — không nói rõ nếu submit 2 lần liên tiếp, nếu mất mạng giữa lúc submit thì sao.
  • Động từ mơ hồ về scope: "cập nhật", "đồng bộ" — cập nhật toàn bộ hay chỉ field thay đổi? Đồng bộ ngay lập tức hay theo batch?
  • Thiếu chủ thể thời gian: "Sau khi thanh toán thành công" — bao lâu sau? Ngay lập tức hay có thể delay do webhook?

Ví dụ minh họa (trước/sau):

AC gốc (ambiguous): "Khi user nhập sai OTP nhiều lần, hệ thống phải khóa tài khoản tạm thời."

Vấn đề AI phát hiện: "nhiều lần" không có số cụ thể; "tạm thời" không có thời gian; không nói rõ khóa account hay khóa chức năng nhập OTP; không có behavior khi OTP hết hạn trong lúc đang đếm sai.

Câu hỏi clarify: Ngưỡng sai bao nhiêu lần thì khóa? Khóa bao lâu? Khóa toàn bộ account hay chỉ chặn nhập OTP? Đếm số lần sai theo phiên hay theo ngày?

Tìm Edge Case Còn Thiếu Trong AC

Missing edge case là lỗ hổng coverage phổ biến nhất và khó phát hiện nhất, vì bản chất của nó là "cái không được viết ra". Một kỹ thuật hiệu quả là yêu cầu AI generate edge case theo các category chuẩn của QA, rồi so khớp với AC gốc để tìm phần bị bỏ sót:

Dựa trên AC sau đây cho feature "{tên feature}":
"""
{AC gốc}
"""

Hãy liệt kê các edge case CÓ KHẢ NĂNG xảy ra trong thực tế nhưng KHÔNG được đề cập trong AC, theo các nhóm:
1. Boundary values (giá trị biên: 0, giá trị âm, giá trị max, chuỗi rỗng, ký tự đặc biệt)
2. Concurrency (nhiều user/request cùng thao tác, race condition)
3. Network/System failure (mất kết nối giữa lúc thao tác, timeout, retry)
4. Permission/Role (user không đủ quyền, session hết hạn giữa thao tác)
5. Data state (dữ liệu liên quan đã bị xóa/thay đổi bởi thao tác khác)
6. Localization/Format (định dạng ngày giờ, ký tự Unicode, số thập phân theo locale)

Với mỗi edge case, đánh giá mức độ rủi ro (Cao/Trung bình/Thấp) nếu AC không xử lý rõ trường hợp này.

Kết quả từ prompt này không phải để copy nguyên vào test case — mà là danh sách để bạn lọc lại, giữ những edge case thực sự relevant với nghiệp vụ, rồi đưa vào phần "câu hỏi cần clarify" gửi cho Dev/PO.

Mẹo: Chạy đồng thời 2 prompt trên (audit ambiguity + tìm missing edge case) cho toàn bộ AC trong một Epic/User Story ngay khi ticket vừa refine xong, trước khi Dev bắt đầu code. Làm sớm 1-2 ngày giúp câu trả lời clarify về kịp trước khi code viết theo hướng sai, tránh phải rework cả code và test case sau này.

Làm Sao Để Nêu Vấn Đề Testability Sớm Bằng Feedback AI Tạo Ra?

Phát hiện vấn đề trong AC chỉ có giá trị nếu feedback đến đúng người, đúng lúc, đúng cách. Feedback mơ hồ ("AC này chưa rõ") hoặc feedback đến muộn (sau khi Dev code xong) đều làm giảm giá trị của việc audit. Phần này tập trung vào cách đóng gói output từ AI thành feedback hành động được, và cách đưa feedback vào workflow của team mà không làm chậm sprint.

Cấu Trúc Feedback AC Cho Development Team

Feedback tốt nhất nên có 4 phần: AC gốc (trích dẫn), vấn đề cụ thể, mức độ ảnh hưởng, và đề xuất cụ thể. Tránh feedback dạng "câu này khó hiểu" — luôn kèm theo câu hỏi cụ thể hoặc phiên bản đề xuất.

Dùng prompt sau để chuyển output audit thô thành comment sẵn sàng post lên Jira/ticket:

Từ kết quả audit AC sau:
"""
{output từ prompt audit ở phần trước}
"""

Hãy viết thành comment ngắn gọn để post lên Jira ticket, dành cho Product Owner và Dev đọc trong 30 giây.
Format:
- Mỗi vấn đề 1 dòng, dùng emoji mức độ: 🔴 Blocker (không thể viết test case nếu không clarify) / 🟡 Cần xác nhận (có thể giả định tạm nhưng nên confirm) / 🔵 Gợi ý bổ sung (không bắt buộc, nên có để tăng coverage)
- Với mỗi dòng 🔴 và 🟡, kèm câu hỏi cụ thể dạng có thể trả lời Yes/No hoặc chọn 1 trong các option
- Giọng văn: hợp tác, không phán xét, tập trung vào rủi ro chứ không phải "chê" AC

Việc phân loại 🔴/🟡/🔵 rất quan trọng — nó cho PO biết ngay cái nào chặn tiến độ, cái nào có thể xử lý sau. Không phải mọi finding từ AI audit đều đáng dừng sprint để hỏi lại.

Yêu Cầu Clarify AC Mà Không Chặn Sprint

Một sai lầm phổ biến của QA mới là gửi 15 câu hỏi clarify cùng lúc và chờ trả lời hết mới bắt đầu viết test case — làm nghẽn cả sprint. Cách xử lý đúng là phân loại câu hỏi theo tính chặn (blocking) và xử lý song song:

  • Blocking questions (🔴): Không có câu trả lời thì không thể xác định pass/fail criteria cơ bản. Gửi riêng, ưu tiên, yêu cầu trả lời trong ngày (thường qua kênh chat trực tiếp, không chờ họp).
  • Non-blocking questions (🟡): Có thể giả định tạm theo convention có sẵn (ví dụ: mặc định theo pattern đã áp dụng ở feature tương tự trước đó), ghi rõ giả định vào test case, và đánh dấu "cần confirm trước khi merge" — vẫn viết test case song song, không chờ.
  • Enhancement suggestions (🔵): Không cần hỏi ngay, đưa vào ticket riêng hoặc note vào Definition of Done cho lần review sau.

Kỹ thuật "giả định tạm có ghi chú" (documented assumption) là chìa khóa để không block sprint: bạn viết test case dựa trên giả định hợp lý nhất, nhưng note rõ "Giả định: OTP sai tối đa 5 lần dựa theo pattern hiện có ở module login — cần PO confirm" ngay trong test case hoặc test plan. Nếu giả định sai, sửa 1 chỗ; nếu giả định đúng, không mất thời gian chờ.

Xây Dựng Testability Quality Gate

Để việc audit AC không phụ thuộc vào "hôm nay QA có rảnh không", nên biến nó thành quality gate chính thức trong Definition of Ready (DoR) — điều kiện để một ticket được coi là "sẵn sàng" đưa vào sprint. Gate đơn giản có thể gồm:

  1. AC đã chạy qua prompt audit ambiguity/edge case (tool AI nội bộ hoặc thủ công theo checklist SMART).
  2. Không còn 🔴 Blocker nào chưa trả lời.
  3. Ít nhất 1 test case mẫu (happy path) đã được viết thử từ AC — nếu viết được nghĩa là AC đủ testable.
  4. Non-functional AC (performance, security, accessibility nếu áp dụng) đã được rà theo checklist riêng (xem phần dưới).

Gate này nên được review trong buổi Backlog Refinement hoặc Sprint Planning, không phải sau khi Dev đã bắt đầu code. Nhiều team gắn gate này vào Jira workflow bằng một custom field "Testability Reviewed: Yes/No" — ticket không được chuyển sang "Ready for Dev" nếu field này chưa Yes.

Escalate Các Vấn Đề Testability Nghiêm Trọng

Không phải mọi vấn đề AC đều xử lý được ở cấp QA-Dev. Có những trường hợp AC mơ hồ đến mức phản ánh một khoảng trống về business rule mà chính PO cũng chưa quyết định — ví dụ chính sách hoàn tiền, quy định compliance, hoặc logic tính phí phức tạp liên quan pháp lý. Đây là lúc cần escalate lên đúng cấp, không tự quyết hay tự đoán.

Dấu hiệu cần escalate thay vì tự xử lý trong team:
- Câu hỏi clarify chạm đến business rule ảnh hưởng tài chính, pháp lý, hoặc dữ liệu người dùng (privacy, security).
- PO trả lời "để tôi hỏi lại" nhiều lần cho cùng một AC — dấu hiệu chưa có quyết định thực sự ở cấp business.
- AC mâu thuẫn trực tiếp với AC của một feature khác đã release, ảnh hưởng đến hành vi hệ thống hiện tại.
- Sau 2 vòng clarify, AC vẫn không đạt SMART — có thể do feature chưa được định nghĩa đủ rõ ở cấp product, không phải lỗi viết AC.

Khi escalate, dùng đúng format: nêu rủi ro (không phải chỉ nêu "AC chưa rõ"), nêu tác động nếu không xử lý (ví dụ: "Nếu không rõ ngưỡng khóa OTP, không thể xác định team có đạt yêu cầu security audit hay không"), và đề xuất người/vai trò cần ra quyết định.

Mẹo: Giữ một "AC Clarification Log" dùng chung cho cả team (Confluence, Notion, hoặc sheet đơn giản) ghi lại mọi câu hỏi đã hỏi và câu trả lời đã nhận theo từng Epic. Sau vài sprint, log này trở thành nguồn tham khảo cực giá trị — nhiều câu hỏi lặp lại (ví dụ convention xử lý lỗi mạng) chỉ cần tra log thay vì hỏi lại PO, giảm hẳn số lần escalate không cần thiết.

Làm Sao Để Biến Acceptance Criteria Yếu Thành Điều Kiện Có Cấu Trúc, Test Được?

Audit chỉ là bước phát hiện vấn đề — giá trị thực sự nằm ở việc chuyển AC yếu thành phiên bản test được, để cả Dev và QA dùng chung một bản AC rõ ràng làm nguồn sự thật (source of truth). Đây là kỹ năng viết lại (rewrite), không phải chỉ liệt kê lỗi.

Framework Rewrite AC

Khung rewrite gồm 4 bước, áp dụng nhất quán cho mọi AC yếu:

  1. Tách chủ thể - hành động - kết quả: Xác định rõ ai/cái gì thực hiện hành động, hành động là gì, kết quả quan sát được là gì.
  2. Gắn số/ngưỡng cụ thể: Thay mọi tính từ mơ hồ bằng giá trị đo được, lấy từ business rule đã confirm (không tự bịa).
  3. Chuyển sang format Given-When-Then: Cấu trúc BDD (Behavior-Driven Development) giúp AC tự nhiên trở nên testable vì buộc phải nêu rõ tiền điều kiện (Given), hành động (When), kết quả (Then).
  4. Rà lại theo SMART filter: Sau khi viết lại, chạy lại 5 câu hỏi SMART ở phần đầu bài để xác nhận AC mới đạt chuẩn.

Prompt hỗ trợ rewrite:

Viết lại AC sau theo format Given-When-Then, dựa trên các câu trả lời clarify đã có (liệt kê dưới đây).
Giữ đúng business rule đã confirm, KHÔNG thêm rule mới ngoài thông tin được cung cấp.

AC gốc:
"""
{AC gốc}
"""

Thông tin clarify đã nhận:
"""
{câu trả lời từ PO/Dev, ví dụ: "sai OTP tối đa 5 lần, khóa 15 phút, chỉ khóa chức năng nhập OTP không khóa toàn account"}
"""

Output: liệt kê từng AC con theo format:
Given [tiền điều kiện]
When [hành động]
Then [kết quả quan sát được, có giá trị/ngưỡng cụ thể]

Nếu AC gốc chứa nhiều điều kiện gộp trong 1 câu, tách thành nhiều AC con riêng biệt (atomic).

Ví dụ minh họa đầy đủ (trước/sau) từ AC OTP ở phần trước:

Trước: "Khi user nhập sai OTP nhiều lần, hệ thống phải khóa tài khoản tạm thời."

Sau (rewrite):
- Given user đã nhập sai OTP 4 lần liên tiếp trong cùng phiên xác thực, When user nhập sai OTP lần thứ 5, Then hệ thống khóa chức năng nhập OTP của tài khoản đó trong 15 phút và hiển thị thông báo "Bạn đã nhập sai quá 5 lần, vui lòng thử lại sau 15 phút".
- Given tài khoản đang bị khóa nhập OTP, When user thử nhập OTP trong thời gian khóa, Then hệ thống chặn request và không tính là một lần thử mới.
- Given tài khoản đã hết thời gian khóa 15 phút, When user nhập lại OTP, Then hệ thống cho phép nhập lại và reset bộ đếm số lần sai về 0.

Tách AC Multi-Intent Thành Điều Kiện Atomic

AC "multi-intent" là AC gộp nhiều điều kiện/kết quả khác nhau trong một câu — dấu hiệu nhận biết là câu có nhiều liên từ "và", "hoặc", hoặc nhiều mệnh đề động từ. Ví dụ: "Khi user submit đơn hàng, hệ thống lưu đơn hàng, gửi email xác nhận, và cập nhật số lượng kho." — đây thực chất là 3 AC khác nhau, mỗi cái cần test case riêng vì có thể pass/fail độc lập (email gửi lỗi không có nghĩa là lưu đơn hàng cũng lỗi).

Nguyên tắc tách atomic: mỗi AC con chỉ nên có đúng 1 kết quả quan sát được để pass/fail rõ ràng, không phụ thuộc kết quả của AC con khác. Cách nhận diện nhanh: nếu bạn phải dùng từ "và" để nối 2 assertion khác nhau trong 1 test case, đó là dấu hiệu AC chưa atomic.

Trước (multi-intent): "Khi user submit đơn hàng hợp lệ, hệ thống lưu đơn hàng, gửi email xác nhận, và trừ số lượng kho tương ứng."

Sau (atomic):
- AC1: Given đơn hàng hợp lệ, When user submit, Then đơn hàng được lưu vào hệ thống với status "Confirmed".
- AC2: Given đơn hàng đã lưu thành công, When quá trình submit hoàn tất, Then email xác nhận được gửi đến địa chỉ email của user trong vòng 5 phút.
- AC3: Given đơn hàng đã lưu thành công, When quá trình submit hoàn tất, Then số lượng kho của từng sản phẩm trong đơn giảm đúng bằng số lượng đã mua.

Tách atomic không chỉ giúp viết test case rõ ràng — nó còn giúp Dev debug nhanh hơn khi 1 trong 3 luồng lỗi (ví dụ email service down) không làm sai lệch việc đánh giá 2 AC còn lại.

Bổ Sung Non-Functional AC Còn Thiếu

Phần lớn AC do PO viết chỉ tập trung vào functional behavior — cái hệ thống "làm gì". Non-functional AC (performance, security, accessibility, khả năng chịu lỗi) thường bị bỏ qua hoàn toàn vì không nằm trong tư duy "user story" thông thường, nhưng lại chính là nguồn gốc nhiều incident nghiêm trọng ngoài production.

Checklist non-functional nên rà cho mọi feature quan trọng:

  • Performance: Ngưỡng response time, số lượng record/request đồng thời hệ thống phải chịu được.
  • Security: Ai được phép thực hiện hành động này? Dữ liệu nhạy cảm có được mask/encrypt khi hiển thị/log không?
  • Accessibility: Nếu có UI, có yêu cầu tối thiểu về keyboard navigation, screen reader không?
  • Error resilience: Hệ thống hành xử thế nào khi dependency (API bên thứ 3, database) không phản hồi?
  • Data integrity: Nếu thao tác bị gián đoạn giữa chừng (mất mạng, crash), dữ liệu có ở trạng thái nhất quán không?

Prompt để gợi ý non-functional AC còn thiếu:

Dựa trên AC functional sau cho feature "{tên feature}":
"""
{AC functional gốc}
"""

Đề xuất các AC non-functional còn thiếu, theo nhóm: Performance, Security, Accessibility, Error resilience, Data integrity.
Chỉ đề xuất nếu thực sự relevant với loại feature này (ví dụ: không đề xuất Accessibility cho một background job không có UI).
Với mỗi đề xuất, viết dưới dạng Given-When-Then, và ghi rõ đây là ĐỀ XUẤT cần Product Owner/Tech Lead xác nhận ngưỡng cụ thể, không tự đặt số liệu.

Lưu ý quan trọng: AI có thể gợi ý đúng loại non-functional cần có, nhưng KHÔNG nên tự đặt ngưỡng cụ thể (ví dụ "phải nhanh hơn 200ms") nếu không có cơ sở — ngưỡng đó phải đến từ NFR (Non-Functional Requirement) đã thống nhất, SLA hiện có, hoặc benchmark thực tế của hệ thống.

Validate AC Đã Rewrite So Với Intent Gốc

Rewrite AC theo Given-When-Then dễ mắc lỗi "trượt scope" — vô tình thêm hoặc bớt ý so với AC gốc, đặc biệt khi tách atomic nhiều AC con. Bước cuối cùng, không thể bỏ qua, là validate lại bản rewrite so với AC gốc và với intent thực sự của Product Owner.

Cách validate hiệu quả:

  1. Diff ngược lại bằng AI: Đưa cả AC gốc và bản rewrite cho AI, yêu cầu chỉ ra: (a) ý nào trong AC gốc bị mất khi rewrite, (b) ý nào được thêm vào mà không có trong AC gốc hoặc trong clarify đã nhận.
  2. Đọc lại cùng PO trong 2 phút: Không cần họp dài — gửi bản rewrite kèm câu hỏi "Bản này có đúng ý anh/chị muốn không?" ngay trên comment ticket, để PO xác nhận bằng 1 câu trả lời.
  3. Thử map ngược sang test case: Nếu từ bản rewrite bạn viết được test case rõ ràng ngay, không cần đoán thêm gì — đó là dấu hiệu rewrite đạt chuẩn testable.

Prompt hỗ trợ diff:

So sánh AC gốc và AC đã rewrite dưới đây. Chỉ ra:
1. Ý nào có trong AC gốc nhưng bị thiếu/thay đổi nghĩa trong bản rewrite
2. Ý nào có trong bản rewrite nhưng KHÔNG có cơ sở từ AC gốc hoặc từ thông tin clarify đã cung cấp (khả năng AI tự suy diễn thêm)

AC gốc:
"""
{AC gốc}
"""

AC đã rewrite:
"""
{AC rewrite}
"""

Thông tin clarify đã có:
"""
{câu trả lời clarify}
"""

Bước validate này không phải thủ tục hình thức — nó là lưới an toàn cuối cùng chống lại "AI hallucination" (AI tự bịa thông tin không có thật) lẻn vào requirement chính thức. Một AC rewrite sai do AI tự suy diễn, nếu không bị bắt lại ở bước này, sẽ trở thành nguồn sự thật sai cho toàn bộ test case và code phía sau — lỗi tốn kém gấp nhiều lần so với chi phí validate 2 phút.

Mẹo: Luôn lưu cả bản AC gốc và bản đã rewrite trong ticket (đừng xóa bản gốc) kèm tên người đã confirm rewrite. Khi có tranh chấp về scope sau này ("tôi không nói vậy"), bạn có bằng chứng rõ ràng ai đã confirm điều gì, thay vì chỉ có ký ức mơ hồ của các bên.