·

Tiếng Việt: Hands-on: Generate and maintain a full manual test suite

Hands-on: Generate and maintain a full manual test suite

Đây là bài thực hành tổng hợp toàn bộ module — không giới thiệu kỹ thuật mới, mà đi qua từng bước thực tế trên một feature cụ thể, từ generate suite lần đầu, tới việc feature đó có code thay đổi, tới việc review/finalize và cập nhật suite sau thay đổi. Nếu bạn đã đọc 5 bài trước, bài này là nơi ráp mọi kỹ thuật lại thành một quy trình làm việc liền mạch mà bạn có thể áp dụng ngay cho feature thật của mình.

Làm Thế Nào Để Tạo Một Manual Test Suite Hoàn Chỉnh Từ User Story và Design Spec?

Feature Thực Hành: Chỉnh Sửa Hồ Sơ Người Dùng (User Profile Edit)

Feature dùng cho bài thực hành: cho phép user đã đăng nhập chỉnh sửa display name, ảnh đại diện (avatar), và bio trên trang hồ sơ cá nhân. Acceptance criteria gồm: display name 2-50 ký tự không cho phép khoảng trắng đầu/cuối; avatar chấp nhận JPG/PNG tối đa 5MB, phải crop tỉ lệ 1:1 trước khi upload; bio tối đa 280 ký tự; nếu upload lỗi, hiển thị lỗi inline, không redirect. Đây chính là feature đã dùng làm ví dụ rải rác ở các bài trước — giờ ta ráp toàn bộ context đó lại thành một lượt generate đầy đủ.

Bước 1: Chạy Prompt Trích Xuất Context Đầy Đủ

Áp dụng đúng template thứ tự context đã học ở bài 2 (ROLE → TASK → OUTPUT FORMAT → AC → USER ROLES → DATA CONSTRAINTS → DESIGN CONTEXT → FEATURE DESCRIPTION), cộng thêm yêu cầu coverage đầy đủ đã học ở bài 1 và 3:

ROLE

You are a senior QA engineer writing manual test cases for a web
application, experienced in equivalence partitioning, boundary
value analysis, and negative-path design.

TASK

Generate a complete manual test suite for the "Edit Profile" feature
described at the end of this prompt. Apply equivalence partitioning
and boundary value analysis to all constrained fields. Include
positive paths, negative paths (business-rule, system-state,
concurrency, external-dependency categories), and edge cases.

COVERAGE REQUIREMENTS

- At least 1 positive test case per acceptance criterion
- At least 1 negative test case per constrained field
- Boundary values for display_name (2/50 chars) and bio (280 chars)
- At least 40% of total test cases must be negative or edge

OUTPUT FORMAT

Markdown table: | Test ID | Title | Precondition | Steps | Expected
Result | Type | Linked AC |
ID format: PROFILE-EDIT-[POS|NEG|EDGE]-[NNN]

ACCEPTANCE CRITERIA

AC-01: Display name must be 2-50 characters, no leading/trailing space
AC-02: Avatar accepts JPG/PNG only, max 5MB, must be cropped 1:1
AC-03: Bio max 280 characters, emoji allowed
AC-04: Upload failure shows inline error, does not redirect

USER ROLES

- Guest (cannot access this screen, should be redirected to login)
- Registered member (primary actor)
- Admin editing another user's profile via admin panel (secondary actor)

DATA CONSTRAINTS

| Field        | Type   | Required | Min | Max  | Notes                |
|--------------|--------|----------|-----|------|----------------------|
| display_name | string | yes      | 2   | 50   | no leading/trailing space |
| avatar_file  | file   | no       | -   | 5MB  | jpg, png only, cropped 1:1 |
| bio          | string | no       | 0   | 280  | emoji allowed        |

DESIGN CONTEXT

- Save button disabled until at least one field changes
- Loading state: spinner overlay, all inputs disabled during save
- Error state: red banner on form, user's unsaved input is preserved
- Empty bio: textarea shows placeholder "Tell us about yourself"

FEATURE DESCRIPTION

As a registered user, I want to edit my display name, avatar, and
bio on my profile page, so other users see accurate, up-to-date
information about me. Changes take effect immediately after saving
and are visible to other users without needing to refresh.

Review Output Ban Đầu

Sau khi chạy prompt trên, đừng import ngay. Áp checklist review đã học ở bài 5: kiểm tra expected result có quan sát được không, precondition đủ cụ thể không, tỉ lệ negative/edge có đạt tối thiểu 40% như đã yêu cầu không. Ở lượt thực hành thực tế, thường phát hiện 2-3 vấn đề phổ biến: case về admin sửa hồ sơ người khác dễ bị AI bỏ sót nếu không nhấn mạnh lại trong TASK; case boundary cho bio 280 ký tự cần double-check theo đúng kỹ thuật "multi-byte character" đã học ở bài 3 nếu hệ thống hỗ trợ emoji.

Mẹo: Sau lượt generate đầu tiên, luôn chạy riêng một prompt đếm: "Count how many generated test cases are Positive vs Negative vs Edge, and confirm the negative+edge ratio meets the 40% minimum requested." — đừng tự đếm bằng mắt, vì rất dễ đếm sai với suite có 20-30+ case.

Làm Thế Nào Để Dùng Mô Hình Dual-Context (Spec + Code Change) Cho Việc Generate Test Case?

Khi Nào Nên Dùng Mô Hình Dual-Context

Mô hình dual-context — đưa cả spec gốc và code/diff thực tế vào cùng một prompt — nên dùng khi bạn nghi ngờ có khoảng cách giữa spec và implementation thật (rất phổ biến: dev implement khác spec một chút do gặp giới hạn kỹ thuật, hoặc spec đã lỗi thời so với code hiện tại). Nếu chỉ dùng spec, bạn test đúng theo ý định nhưng có thể bỏ sót hành vi thật; nếu chỉ dùng code/diff, bạn test đúng hành vi thật nhưng có thể hợp thức hóa một bug thành "hành vi đúng" vì không biết ý định ban đầu khác đi.

Cấu Trúc Prompt Dual-Context

FEATURE SPECIFICATION

[paste AC-01 to AC-04 as in Step 1 above]

CODE / DIFF

[paste relevant PR diff or pseudo-code of the validation logic]
TASK: Compare the FEATURE SPECIFICATION against the CODE/DIFF.
1. List any discrepancy where the code does NOT match the spec.
2. Generate "Test Cases: Spec Validation" — test cases that verify
   the spec's intended behavior (use these to catch cases where the
   code is wrong and needs a bug report).
3. Generate "Test Cases: Implementation-Aware Tests" — test cases
   that verify behavior only visible by reading the actual code
   (e.g., an internal retry limit not mentioned in the spec).

Sự Khác Biệt Giữa Spec và Implementation

Kết quả bước so sánh ở trên thường lộ ra các loại khác biệt: giới hạn số khác (spec ghi 5MB, code check 5,242,880 bytes = đúng 5MB nhưng làm tròn UI hiển thị "5MB" gây hiểu nhầm ranh giới thật); rule ẩn không có trong spec (ví dụ code có retry 3 lần khi upload lỗi mạng, spec không đề cập); hoặc rule spec có nhưng code chưa implement (ví dụ spec nói phải crop 1:1 nhưng code hiện tại chưa validate tỉ lệ ảnh, chỉ validate định dạng/size).

Test Case: Spec Validation

Nhóm test case này dùng để kiểm tra xem code có implement đúng ý định ban đầu — nếu case này fail khi thực thi, đó là bug cần báo, không phải test case cần sửa lại theo hành vi hiện tại.

Test Case: Implementation-Aware Tests

Nhóm test case này dùng để bảo vệ hành vi thật đang chạy trong production (dù không có trong spec chính thức) — quan trọng để không vô tình phá vỡ hành vi người dùng đang phụ thuộc vào, ngay cả khi hành vi đó chưa từng được viết thành spec.

Áp Dụng Dual-Context Cho Feature Chỉnh Sửa Hồ Sơ

Giả sử team gửi bạn một PR diff thực tế cho phần validate avatar. Ta feed cả AC-02 (spec) và diff (code) vào cùng một prompt để so sánh:

FEATURE SPECIFICATION (relevant sections)

AC-02: Avatar accepts JPG/PNG only, max 5MB, must be cropped 1:1

PR DIFF (summarized)

function validateAvatar(file) {
  const allowed = ['image/jpeg', 'image/png', 'image/gif']; // GIF added
  if (!allowed.includes(file.type)) return 'INVALID_FORMAT';
  const maxSize = file.type === 'image/gif' ? 8_000_000 : 5_000_000;
  if (file.size > maxSize) return 'FILE_TOO_LARGE';
  // NOTE: no aspect-ratio check found in this function
  return 'VALID';
}

Nhận Diện Discrepancy Giữa Spec và Implementation

Với ví dụ trên, prompt sẽ trả về ít nhất 2 discrepancy đáng báo cáo: (1) code đã hỗ trợ GIF với giới hạn 8MB riêng — spec AC-02 chưa được cập nhật để phản ánh điều này (có thể spec lỗi thời, hoặc đây là thay đổi chưa được duyệt chính thức, cần hỏi lại PO); (2) code không có bước validate tỉ lệ ảnh 1:1 như AC-02 yêu cầu — đây là khoảng cách cần báo bug hoặc xác nhận lại xem crop được xử lý ở tầng UI (trước khi gửi request) thay vì ở backend. Cả hai discrepancy này chỉ lộ ra nhờ mô hình dual-context — nếu chỉ đọc spec, bạn sẽ viết test case sai (test GIF sẽ bị reject, nhưng thực tế code đã accept).

Mẹo: Nếu không có PR diff thật trong tay, dùng pseudo-code hoặc vài dòng mô tả logic if/else ngắn gọn cũng đủ hiệu quả cho mô hình dual-context — điều AI cần là thấy được điều kiện rẽ nhánh cụ thể (ví dụ ngưỡng 8MB cho GIF), không nhất thiết phải là diff đúng định dạng Git.

Làm Thế Nào Để Review, Sửa và Hoàn Thiện Output Test Suite do AI Tạo?

Quy Trình Hoàn Thiện (Finalization Workflow)

Quy trình khuyến nghị theo 5 bước: (1) generate suite thô từ Bước 1; (2) chạy dual-context để phát hiện discrepancy nếu có PR liên quan; (3) áp checklist review bài 5, sửa trực tiếp các case bị flag; (4) chạy AI self-review lần 2 (đóng vai QA lead khắt khe, như đã học ở bài 1) để bắt lỗi sót; (5) import vào test management tool theo quy trình bulk import ở bài 1.

Lượt Sửa (Edit Pass): Sửa Gì và Sửa Như Thế Nào

Ở lượt sửa, ưu tiên theo đúng thứ tự mức độ nghiêm trọng: sửa expected result không quan sát được trước (ảnh hưởng khả năng thực thi test), sau đó sửa precondition mơ hồ, cuối cùng mới sửa văn phong/từ vựng. Với case liên quan tới discrepancy phát hiện ở bước dual-context (ví dụ case về GIF), quyết định rõ: nếu spec đúng và code sai → viết test case theo spec, gắn cờ "expected to fail, bug pending"; nếu code đúng và spec lỗi thời → viết test case theo code, ghi chú cần cập nhật spec chính thức.

Dùng AI Cho Lượt Ý Kiến Thứ Hai (Second Opinion Pass)

Sau khi bạn tự sửa xong, chạy một lượt AI review độc lập nữa (session mới, không kèm lịch sử đã sửa) để có góc nhìn "sạch", không bị ảnh hưởng bởi các quyết định sửa trước đó:

ROLE: You are an independent QA reviewer seeing this test suite
for the first time. You have NOT seen any prior version.

Review the suite below purely against the acceptance criteria and
data constraints provided. Flag anything that looks incomplete,
inconsistent, or ambiguous — do not assume prior review already
caught everything.

Import và Tổ Chức

Sau lượt ý kiến thứ hai, import theo cấu trúc folder đã học ở bài 4 — với feature CRUD như Edit Profile, tổ chức theo hành động (Update display name / Update avatar / Update bio / Permissions), gắn metadata source, generated_by, review_status, prompt_version ngay khi import, và cập nhật traceability matrix ngay sau khi import xong, không để lại "làm sau".

Mẹo: Trước khi đóng task, tự chạy lại prompt "regenerate traceability matrix" (bài 4) một lần cuối để chắc chắn không có AC nào bị bỏ sót sau tất cả các lượt sửa — sửa tay nhiều lần dễ làm lệch mapping đã thiết lập từ đầu.

Làm Thế Nào Để Cập Nhật Một Test Suite AI-Generated Đã Có Sau Khi Code Thay Đổi?

Nguyên Tắc "Maintenance Là Re-generation"

Nguyên tắc thực dụng nhất khi maintain suite bằng AI: thay vì sửa tay từng test case bị ảnh hưởng, hãy đưa cả suite hiện tại + thay đổi mới vào một prompt và để AI re-generate lại toàn bộ các case bị ảnh hưởng theo đúng chuẩn hiện tại (không đúng chuẩn cũ mà case đó được viết lúc trước) — miễn là bạn luôn review output trước khi ghi đè, như đã nhấn mạnh xuyên suốt module.

Tình Huống: AC-03 Thay Đổi Để Cho Phép Upload GIF

Tiếp nối ví dụ discrepancy ở trên — giả sử team quyết định chính thức hóa việc hỗ trợ GIF, cập nhật spec: AC-02 giờ ghi "Avatar accepts JPG/PNG/GIF; GIF max 8MB, JPG/PNG max 5MB". Áp dụng đúng prompt phân tích tác động đã học ở bài 4:

CHANGE DESCRIPTION:
"AC-02 updated: avatar now officially supports GIF with 8MB limit,
separate from JPG/PNG's 5MB limit. Aspect-ratio crop requirement
removed (handled client-side only, not testable server-side)."

EXISTING TEST CASES: [paste PROFILE-EDIT-* suite from Step 1]

TASK: Classify each test case as NO CHANGE / NEEDS UPDATE / NOW
OBSOLETE. For NEEDS UPDATE, provide the corrected test case inline.
List any NEW test cases needed for the GIF-specific boundary (8MB).

Quy Trình Cập Nhật Theo Lô Cho Sprint-End Maintenance

Với nhiều thay đổi tích lũy trong sprint (không chỉ 1 AC), lặp lại quy trình phân tích tác động cho từng PR đã merge (theo đúng nguyên tắc "phân tích theo PR riêng lẻ" ở bài 4), gom toàn bộ kết quả NEEDS UPDATE/NOW OBSOLETE/NEW vào một batch review cuối sprint, xử lý cùng lúc, rồi cập nhật changelog cho từng test case bị đổi (theo format đã học ở bài 4) trước khi đóng sprint.

Ngăn Ngừa Nợ Duy Trì (Maintenance Debt)

Nợ duy trì tích lũy khi phân tích tác động bị trì hoãn nhiều sprint liên tiếp — tới lúc đó, số lượng thay đổi chồng chéo quá lớn, AI (và cả con người) khó phân tích chính xác case nào ảnh hưởng bởi thay đổi nào. Biện pháp phòng ngừa chính: biến phân tích tác động thành nghi thức cố định mỗi sprint (đã nói ở bài 4), không gộp dồn; luôn cập nhật changelog ngay khi sửa, không để "nhớ ghi sau"; và định kỳ (mỗi quý) chạy lại toàn bộ quy trình dedup + audit (bài 4) để dọn phần trùng lặp/lỗi thời có thể đã lọt qua trong các lượt cập nhật nhanh theo sprint.

Mẹo: Khi để AI re-generate case bị ảnh hưởng, luôn giữ nguyên Test ID cũ nếu hành vi cốt lõi được kiểm tra không đổi — chỉ tạo ID mới khi test case đó thực sự xác minh một hành vi hoàn toàn mới (như case boundary 8MB cho GIF). Đổi ID tùy tiện làm đứt lịch sử truy vết và changelog đã xây dựng từ đầu.