Testing
Level: L6 — AI Coding & Vibe Coding (Bài 8/12 theo thứ tự sản xuất — · Đối tượng: Người đã học bài 53-59, đã sửa xong lỗi mất dữ liệu ở bài
1. Mục tiêu học tập
Phần tiêu đề “1. Mục tiêu học tập”Sau bài này, bạn có thể:
- Giải thích vì sao “thử tay” không thay thế được test tự động khi sản phẩm lớn dần.
- Phân biệt unit test (kiểm tra 1 phần nhỏ, độc lập) và integration test (kiểm tra nhiều phần phối hợp với nhau) — 2 tầng cơ bản nhất của “kim tự tháp kiểm thử.”
- Dùng Claude Code để tìm phần chưa có test, sinh test tự động, và bổ sung edge case theo đúng quy trình chính thức.
- Viết test cho chức năng lưu/đọc ghi chú của dự án tích lũy.
2. Khái niệm cốt lõi
Phần tiêu đề “2. Khái niệm cốt lõi”Vì sao cần test tự động (không phải chỉ “thử tay”): ở bài 59, bạn tự tay tái hiện lỗi mất dữ liệu để xác minh đã sửa xong — cách này hiệu quả cho 1 lỗi cụ thể, nhưng không mở rộng được: mỗi lần thêm 1 tính năng mới (bài 60, 64), bạn sẽ phải nhớ tự tay thử lại toàn bộ tính năng cũ để chắc chắn không có gì hỏng. Test tự động là cách ghi lại vĩnh viễn một lần “thử tay đúng cách”, để chạy lại bất cứ khi nào chỉ trong vài giây.
Kim tự tháp kiểm thử (test pyramid — kiến thức chuyên môn phổ quát, không gắn 1 công cụ AI nào):
- Unit test (đáy kim tự tháp, nhiều nhất) — kiểm tra 1 đơn vị nhỏ, độc lập, ví dụ: “hàm xóa ghi chú có xóa đúng ghi chú theo ID không, mà không ảnh hưởng ghi chú khác.” Chạy rất nhanh, dễ xác định lỗi nằm ở đâu khi fail.
- Integration test (giữa kim tự tháp, ít hơn) — kiểm tra nhiều phần phối hợp, ví dụ: “khi người dùng bấm nút thêm ghi chú ở Frontend, dữ liệu có thực sự tới được Database qua đúng API không” (đúng mô hình 4 lớp bài 55). Chạy chậm hơn unit test, nhưng phát hiện được lỗi giữa các lớp mà unit test từng lớp riêng lẻ không thấy.
Level 6 chỉ cần 2 tầng này — tầng cao nhất của kim tự tháp đầy đủ (kiểm thử toàn bộ giao diện người dùng tự động, “end-to-end”) vượt phạm vi người mới bắt đầu, không bắt buộc cho dự án tích lũy.
Quy trình chính thức “Work with tests” khi làm việc với Claude Code [S98]:
- Xác định code chưa có test — ví dụ nguyên văn: “find functions… that are not covered by tests.”
- Sinh khung test (scaffolding) — ví dụ: “add tests for the notification service.”
- Thêm test case có ý nghĩa, đặc biệt edge case (tình huống biên, bất thường) — ví dụ: “add test cases for edge conditions.”
- Chạy và xác minh test, sửa lỗi nếu có — ví dụ: “run the new tests and fix any failures.”
Verified fact quan trọng: Claude Code đọc các file test hiện có của dự án để khớp đúng style/framework/assertion pattern đang dùng — không tự bịa convention mới [S98]. Để có coverage toàn diện, có thể chủ động yêu cầu AI tìm edge case, lỗi biên, input bất ngờ mà con người dễ bỏ sót [S98].
3. Tại sao nội dung này quan trọng
Phần tiêu đề “3. Tại sao nội dung này quan trọng”Test là “lưới an toàn” cho mọi thay đổi sau này — đặc biệt cho bài 60 (Refactor), nơi mục tiêu là thay đổi cấu trúc code mà không đổi hành vi: không có test, bạn không có cách nào chắc chắn hành vi thực sự không đổi, chỉ có thể “hy vọng.”
4. Cơ chế hoạt động
Phần tiêu đề “4. Cơ chế hoạt động”Phân định AI vs con người:
| Điều bạn cần hiểu | Điều AI có thể thực hiện | Điều bạn phải xác nhận | |
|---|---|---|---|
| Xác định phạm vi | Tính năng nào quan trọng nhất cần test trước | Quét code, liệt kê phần chưa có test | Danh sách AI đưa ra có đúng ưu tiên đúng tính năng cốt lõi (ví dụ: lưu/đọc dữ liệu quan trọng hơn màu nút bấm) |
| Sinh test | Test cần phản ánh đúng hành vi mong muốn, không phải hành vi hiện tại nếu hiện tại đang sai | Viết khung test theo đúng style dự án | Test có thực sự kiểm tra đúng điều bạn quan tâm, không phải test hình thức “cho có” |
| Edge case | Edge case là tình huống biên dễ bị bỏ sót (ví dụ: ghi chú rỗng, ghi chú rất dài) | Chủ động đề xuất edge case | Danh sách edge case có phủ đúng rủi ro thật của sản phẩm bạn, không chỉ ví dụ chung chung |
| Chạy & xác minh | Test fail nghĩa là có gì đó cần xem lại — đôi khi là code sai, đôi khi là test viết sai | Chạy test, tự sửa nếu fail | Khi test fail, xác định đúng là code sai hay test viết sai trước khi để AI “sửa cho qua” |
5. Mental model
Phần tiêu đề “5. Mental model”Nếu bài 59 là lúc bạn phát hiện và vá 1 vết rò nước cụ thể, bài này là lúc bạn lắp cảm biến rò nước ở những vị trí quan trọng nhất trong nhà — không phải để tránh mọi vết rò tương lai (không thể), mà để biết ngay khi có vết rò mới xuất hiện, thay vì phải tự đi kiểm tra từng phòng mỗi lần.
6. Hướng dẫn từng bước
Phần tiêu đề “6. Hướng dẫn từng bước”Áp dụng cho dự án tích lũy: Trợ Lý Ghi Chú Cá Nhân Có AI Tóm Tắt.
- Xác định phạm vi ưu tiên — chức năng lưu/đọc ghi chú (đã sửa lỗi ở bài 59) là tính năng cốt lõi nhất, ưu tiên test trước các phần khác.
- Yêu cầu Claude Code sinh unit test — ví dụ: “viết unit test cho hàm thêm ghi chú: kiểm tra ghi chú được lưu đúng nội dung.”
- Yêu cầu integration test cho chu trình đầy đủ — ví dụ: “viết integration test: thêm ghi chú qua giao diện, sau đó tải lại — xác nhận ghi chú vẫn còn” — đây chính là phiên bản tự động hóa của bước xác minh bạn từng làm thủ công ở bài 59.
- Bổ sung edge case — ví dụ: ghi chú nội dung rỗng, ghi chú rất dài, xóa ghi chú không tồn tại. Yêu cầu Claude Code chủ động đề xuất thêm trường hợp bạn có thể chưa nghĩ tới.
- Chạy toàn bộ test, xác nhận tất cả pass trước khi coi tính năng là hoàn chỉnh.
7. Ví dụ thực tế
Phần tiêu đề “7. Ví dụ thực tế”Edge case dễ bị bỏ sót cho dự án ghi chú: xóa 1 ghi chú, sau đó thử xóa lại đúng ghi chú đó lần nữa (đã không còn tồn tại) — sản phẩm nên xử lý thế nào (thông báo lỗi rõ ràng, hay im lặng không làm gì)? Đây là loại tình huống người mới thường không tự nghĩ ra khi “thử tay”, nhưng Claude Code có thể chủ động đề xuất nếu được yêu cầu tìm edge case [S98].
8. Prompt/template/workflow
Phần tiêu đề “8. Prompt/template/workflow”Khung yêu cầu test tái sử dụng:
Tìm các chức năng trong [tên file/module] chưa có test.Viết unit test cho [chức năng cụ thể], kiểm tra [hành vi mong muốn].Sau đó, đề xuất thêm edge case tôi có thể chưa nghĩ tới.Chạy toàn bộ test và sửa nếu có lỗi.Checklist trước khi coi 1 tính năng đã có test đầy đủ:
[ ] Có ít nhất 1 unit test cho phần logic cốt lõi?[ ] Có ít nhất 1 integration test cho chu trình đầy đủ (qua đúng API)?[ ] Đã yêu cầu AI đề xuất edge case, không chỉ dùng test "đường thẳng"?[ ] Toàn bộ test đã chạy và pass?9. Visual hoặc diagram cần thiết
Phần tiêu đề “9. Visual hoặc diagram cần thiết”10. Bài tập thực hành
Phần tiêu đề “10. Bài tập thực hành”- Yêu cầu Claude Code liệt kê chức năng nào trong dự án của bạn chưa có test.
- Sinh unit test cho 1 chức năng cốt lõi (ví dụ: thêm hoặc xóa ghi chú).
- Sinh integration test cho chu trình đầy đủ tương ứng.
- Yêu cầu AI đề xuất ít nhất 2 edge case, thêm test cho cả 2.
- Chạy toàn bộ test, xác nhận tất cả pass.
11. Checklist
Phần tiêu đề “11. Checklist”12. Lỗi thường gặp
Phần tiêu đề “12. Lỗi thường gặp”- Chỉ viết test cho “đường thẳng” (happy path) — bỏ qua edge case, khiến test có cảm giác an toàn giả tạo.
- Để AI “sửa test cho qua” khi test fail mà không kiểm tra xem lỗi thực sự nằm ở code hay ở chính test viết sai — có thể vô tình làm test không còn kiểm tra đúng điều cần kiểm tra.
- Coi test là việc “làm sau cùng, nếu còn thời gian” — dẫn tới không có lưới an toàn khi bắt đầu refactor (bài 60) hay thêm tính năng (bài 64).
13. Giới hạn & khi nào KHÔNG nên áp dụng
Phần tiêu đề “13. Giới hạn & khi nào KHÔNG nên áp dụng”- Bài này không dạy kiểm thử giao diện tự động ở tầng cao nhất kim tự tháp (end-to-end UI testing) — vượt phạm vi người mới bắt đầu.
- Bài này không dạy refactor — đó là bài 60; ở đây test chỉ đóng vai trò chuẩn bị nền tảng để bài 60 có thể refactor an toàn (chạy lại test sau mỗi thay đổi để xác nhận hành vi không đổi).
- Test không thay thế được bước xác minh thủ công cuối cùng trước khi deploy (bài 63) — test chỉ kiểm tra được những gì bạn đã nghĩ tới viết thành test case.
14. An toàn & quản trị (Safety/Governance)
Phần tiêu đề “14. An toàn & quản trị (Safety/Governance)”Test tự động không phải “làm cho có” — đây là cơ chế phát hiện sớm chính xác loại rủi ro đã nêu ở bài 56 (code AI-đồng-tác-giả có tỷ lệ lỗi nghiêm trọng cao hơn khi thiếu review). Một bộ test tốt giúp phát hiện lỗi ngay khi vừa phát sinh (ví dụ: sau khi thêm tính năng mới ở bài 64), thay vì để người dùng thật phát hiện ra sau khi deploy (bài 63) — chi phí sửa lỗi lúc đó cao hơn nhiều.
15. Best practices
Phần tiêu đề “15. Best practices”- Viết test cho hành vi mong muốn, không phải copy lại hành vi hiện tại của code (nếu hiện tại đang có lỗi, test sẽ “hợp thức hóa” lỗi đó).
- Ưu tiên test chức năng cốt lõi (lưu/đọc dữ liệu) trước chức năng phụ (giao diện, màu sắc).
- Chạy toàn bộ test sau mỗi thay đổi lớn, không chỉ test của phần vừa sửa — phát hiện sớm nếu 1 thay đổi vô tình làm hỏng phần khác.
16. Nội dung nâng cao (không bắt buộc)
Test tự động còn đóng vai trò là 1 dạng “tài liệu sống”: đọc lại các test case của 1 chức năng cho biết chính xác hành vi mong đợi của chức năng đó là gì, thường rõ ràng hơn đọc code trực tiếp — hữu ích khi bạn (hoặc AI) quay lại 1 phần dự án đã lâu không động tới.
17. Nguồn tham khảo
Phần tiêu đề “17. Nguồn tham khảo”- [S98] Common Workflows, Anthropic — code.claude.com/docs — quy trình chính thức “Work with tests” (xác định phạm vi → sinh khung test → thêm edge case → chạy và xác minh), verified fact về việc AI khớp đúng convention test hiện có của dự án.
- Dẫn chiếu (không trích dẫn mới): bài 55 (mô hình 4 lớp, dùng để phân biệt unit vs integration test), bài 59 (test tự động là phiên bản tự động hóa của bước xác minh thủ công đã học).
18. Ngày kiểm chứng
Phần tiêu đề “18. Ngày kiểm chứng”Quy trình chính thức kiểm chứng qua nguồn Tier 1 (S98) ngày 2026-07-12. Khái niệm kim tự tháp kiểm thử (unit/integration) là kiến thức chuyên môn phổ quát, không phụ thuộc thời điểm — rủi ro lỗi thời thấp.