Cách viết test case và checklist: ví dụ cho web và API
Tài liệu kiểm thử chỉ có giá trị khi người khác có thể lặp lại phép kiểm tra, hiểu phạm vi bao phủ và đưa ra quyết định về chất lượng. Với một luồng checkout, bài này chỉ ra khi nào cần test case chi tiết, khi nào checklist là đủ và cách tránh tài liệu hình thức.
Chọn loại tài liệu trước khi điền template
Cùng một scenario không cần giữ một format mãi mãi. Khi team lần đầu kiểm luồng 3-D Secure, test case chi tiết giúp không bỏ sót trạng thái quay về từ ngân hàng. Khi luồng đã ổn định và team có kinh nghiệm chạy hằng tuần, checklist tập trung sẽ dễ bảo trì hơn.
Quyết định dựa trên rủi ro sản phẩm, độ khó chuẩn bị data, kinh nghiệm người chạy và yêu cầu evidence. Lỗi càng đắt và điều kiện ẩn càng nhiều thì càng cần chi tiết. Một field bắt buộc trong TMS không tự tạo ra giá trị.
| Tình huống | Chọn | Lý do |
|---|---|---|
| Luồng payment mới | Test case | Cần data, step và evidence chính xác |
| Smoke quen thuộc trước release | Checklist | Ưu tiên tốc độ và critical path |
| Kiểm tra có audit | Test case | Cần lặp lại và lưu lịch sử |
| Exploratory session | Charter + note | Không biết trước mọi step hữu ích |
Cấu trúc test case: mọi kết luận phải kiểm chứng được
Bộ tối thiểu hữu ích gồm id, title, link requirement, precondition, test data, action, expected result và execution status. Author, component, priority hay automation chỉ có ích khi team dùng chúng cho ownership hoặc report.
Precondition là trạng thái đã tồn tại: buyer đã login, cart có sản phẩm và currency đã đặt. “Tạo user” là việc setup, không phải trạng thái. Với setup phức tạp, link fixture, API call hoặc data builder tạo trạng thái ổn định.
- Title nêu action, condition và outcome.
- Một step có một action; expected nằm tại nơi có thể quan sát.
- Data cụ thể: test_declined_01 và SKU-1842, không phải “data hợp lệ”.
- Expected bao phủ UI, API, storage và side effect khi chúng nằm trong scope.
- Pass nghĩa là mọi expected quan trọng đã được kiểm tra.
Ví dụ hoàn chỉnh: checkout với thẻ bị từ chối
Requirement: khi provider trả `declined`, order vẫn unpaid, inventory reservation được giải phóng, user thấy message an toàn và có thể thử thẻ khác. Phép kiểm tra đi qua UI, API, storage và integration.
Mỗi expected dưới đây đều quan sát được. “Lỗi được xử lý đúng” là câu yếu vì không cho biết trạng thái order, tiền và reservation.
Priority: High Requirement: PAY-AC-07 Preconditions: - user buyer_17 is signed in - cart has SKU-1842, qty=1 - inventory reservation TTL is 15 minutes Data: card token test_declined_01 1. Open checkout and submit the card Expected: button shows progress and cannot submit twice 2. Wait for POST /payments response Expected: 402; error.code=card_declined; no secret data 3. Open the order Expected: status=payment_failed; paid_at=NULL 4. Check inventory after the agreed processing time Expected: reservation released exactly once 5. Retry with test_approved_01 Expected: one successful charge; order=paid; one confirmation Evidence: request ids, provider stub log, order id, timestamps
Biến cùng rủi ro thành checklist hữu ích
Checklist không phải test case bị cắt bớt. Nó nhóm phạm vi và làm rõ model rủi ro. Mỗi item vẫn nêu object và rule nhưng không ép từng click.
Với checkout, nhóm theo order state, lỗi provider, retry, idempotency và recovery sau timeout. Cách này cho thấy coverage tốt hơn nhật ký di chuyển chuột.
[ ] declined: order is not paid; retry is available [ ] insufficient_funds: user message contains no provider internals [ ] timeout before response: status becomes known after reconciliation [ ] duplicate submit: one charge and one order transition [ ] callback repeated: inventory is released/confirmed once [ ] callback out of order: final state follows the agreed state machine [ ] refresh/back: no second payment request [ ] audit log: request id and transition are traceable
Positive, negative và boundary coverage
Một happy path không chứng minh chất lượng. Chia input thành phương thức payment được phép và bị cấm, giá trị trong và ngoài limit, promotion active và expired, response success, decline, timeout và malformed. Sau đó chọn representative và boundary.
Negative test phải kiểm cả việc side effect bị cấm không xảy ra. Sau 422 không tạo order; sau 403 dữ liệu người khác không đổi; sau timeout retry không được charge hai lần.
| Giá trị | Expected | Mục đích |
|---|---|---|
| 99 | 422; không tạo payment | Dưới lower boundary |
| 100 | Accepted | Lower boundary |
| 101 | Accepted | Ngay bên trong |
| 99.999 | Accepted | Bên trong upper |
| 100.000 | Accepted | Upper boundary |
| 100.001 | 422; không tạo payment | Trên upper boundary |
Test case, checklist và bug report trả lời câu hỏi khác nhau
Test case định nghĩa phép kiểm tra trước execution. Checklist quản lý độ rộng coverage. Bug report ghi mismatch đã quan sát và evidence. Thường không cần copy toàn bộ case vào defect; chỉ giữ setup và action cần để reproduce actual result.
Traceability quan trọng hơn layout. Requirement nối với check, run nối với result, failure nối với defect, fix nối với retest và regression gần đó. Các link giải thích rule mà test bảo vệ.
| Artifact | Câu hỏi | Output |
|---|---|---|
| Test case | Lặp lại phép kiểm tra thế nào? | Pass / Fail / Blocked |
| Checklist | Không được quên rủi ro nào? | Mark và note |
| Bug report | Điều gì trái rule? | Defect có evidence |
| Test report | Đã test gì và release được không? | Kết luận theo risk |
Review: bảy dấu hiệu của một phép kiểm tra tốt
Review model thay vì sở thích format. Hỏi risk nào được bao phủ, expected đến từ đâu, data có lặp lại được không và có phân biệt product failure với environment failure không.
Test cần maintenance. Khi contract đổi, expected cũ tạo false alarm. Owner nên xóa duplicate, gộp setup và giữ lại decision quan trọng thay vì chỉ tăng số lượng case.
- Link requirement hoặc rule hiện tại.
- Title phân biệt được với case bên cạnh.
- Setup và data lặp lại được.
- Expected quan sát được, không dùng “hoạt động đúng”.
- Kiểm material side effect và thay đổi bị cấm.
- Dependency được bỏ hoặc ghi rõ.
- Chi phí bảo trì phù hợp risk được bảo vệ.
Trả lời phỏng vấn mà không đọc thuộc template
Interviewer thường kiểm cách suy luận: bạn có nối tài liệu với context và risk không. Đưa definition một câu, nêu tiêu chí chọn và kết thúc bằng ví dụ cụ thể. Nếu process tùy team, hãy nói rõ và đề xuất cách hợp lý.
Với bài “test login form”, trước tiên làm rõ rule email/password, limit số lần thử, MFA, recovery, role và session. Sau đó trình bày partition, boundary, state và security check. Chỉ nói “login hợp lệ/không hợp lệ” chưa cho thấy coverage.
1. Definition: what the artifact is for 2. Context: risk, team and execution frequency 3. Choice: why test case, checklist or charter 4. Example: concrete data and observable expected result 5. Trade-off: coverage versus maintenance cost 6. Follow-up: what I would clarify before writing it
Câu hỏi thường gặp
Mỗi step có cần expected result không?
Chỉ khi có kết quả quan sát được. Không cần lặp outcome điều hướng hiển nhiên, nhưng không được giấu intermediate state quyết định kết quả cuối.
Có thể lưu test case trong spreadsheet không?
Có, nếu collaboration, history và reporting là đủ. TMS hữu ích cho run, parameter, traceability và analytics; tool không tự làm case tốt hơn.
Mọi manual test case có cần automation không?
Không. Automation phù hợp check ổn định, lặp lại và quan trọng. Exploratory, visual hoặc scenario thay đổi nhanh có thể vẫn manual.
Expected viết gì khi requirement mâu thuẫn?
Không âm thầm chọn. Ghi lại mâu thuẫn, lấy quyết định từ owner và link case với nguồn đã thống nhất. Trước đó check có thể là Blocked thay vì Fail.
Test case tốt không chứng minh người viết biết điền form. Nó làm risk rõ ràng, execution lặp lại được và result hữu ích cho quyết định release.