Tester chạy test case đăng nhập, bấm nút Login xong không thấy gì xảy ra. Thế là mở tool lên log một con bug:
Title: Login lỗi
Steps: Đăng nhập
Actual: Không đăng nhập được
Expected: Đăng nhập được
Xong gán cho dev.
Dev đọc xong sẽ phải hỏi lại: test ở build nào, tài khoản gì, bấm xong đứng im hay báo lỗi, có request đi không, lần nào cũng bị hay thi thoảng mới bị. Cái bug report chưa giúp dev sửa gì cả; nó chỉ chính thức hoá việc tester vừa nhìn thấy một chuyện lạ.
Trước khi log
Thấy test case fail chưa chắc đã phải bug. Có thể test data hết hạn, môi trường đang chết, requirement vừa đổi nhưng test case chưa cập nhật, hoặc chính mình bấm thiếu một bước.
Vậy trước khi log, nên chạy lại ít nhất một lần và nhìn qua mấy thứ cơ bản:
- Mình có làm đúng steps và precondition không?
- Build, environment và test data có đúng không?
- Expected Result lấy từ đâu: requirement, acceptance criteria hay chỉ là mình nghĩ nó nên thế?
- Có reproduce lại được không? Nếu không ổn định thì tần suất khoảng bao nhiêu?
Không cần điều tra đến mức tìm ra dòng code sai rồi mới được log. Đấy là việc cả team cùng làm. Nhưng ít nhất phải chắc rằng có một khác biệt quan sát được giữa actual và expected.
Title để người đọc biết mình sắp đụng vào đâu
Login lỗi, App crash, UI sai đều đúng, nhưng vô dụng vì thiếu ngữ cảnh.
Một title ổn thường trả lời được ba ý: cái gì xảy ra, ở đâu, trong điều kiện nào.
Ví dụ:
[Login] User remains on Login page after submitting a valid admin account
Hoặc nếu team viết tiếng Việt:
[Đăng nhập] Người dùng vẫn ở trang Login sau khi nhập tài khoản admin hợp lệ
Không nhất thiết title nào cũng phải nhét đủ ba vế. Bug crash toàn app thì [Checkout] App crashes when applying an expired voucher là đủ rõ. Đừng biến title thành một đoạn văn, nhưng cũng đừng bắt người đọc mở bug ra mới biết nó thuộc màn hình nào.
Environment và dữ liệu
Bug chỉ xuất hiện trên Safari mà report ghi mỗi chữ Web thì dev test Chrome cả buổi cũng không thấy. Bug chỉ xảy ra với account cũ từ năm ngoái mà không đưa account thì cũng chịu.
Những thông tin thường cần có:
- Environment: Test, Staging hay Production.
- Build/version hoặc commit nếu team có dùng.
- Thiết bị, OS, browser và version khi nó liên quan.
- Test account, role, trạng thái dữ liệu hoặc ID của record.
- Tần suất:
5/5,2/10, hoặc mới gặp đúng một lần.
Không phải bug nào cũng điền nguyên danh bạ máy tính. API trả sai total thì độ phân giải màn hình gần như chẳng giúp gì. Ghi thứ có khả năng ảnh hưởng đến việc reproduce thôi.
Steps càng ngắn càng tốt, nhưng không được hụt
Steps là đường đi ngắn nhất vẫn đưa người khác đến đúng failure.
Ví dụ:
- Mở trang Login trên môi trường Test.
- Nhập tài khoản
admin_01và mật khẩu hợp lệ. - Bấm Login.
Nếu precondition đã nói user đang ở trang Login thì không cần viết thêm “mở Chrome”, “nhập URL”, “chờ trang load” vào mọi bug. Ngược lại, nếu bug chỉ xuất hiện sau khi user logout rồi quay lại bằng nút Back thì bỏ đoạn đó đi là dev không reproduce nổi.
Đây là lý do copy nguyên steps của một test case dài 25 dòng sang bug report thường không hay. Test case chứng minh cả flow; bug report cần cô lập chỗ hỏng.
Expected và Actual phải cắn vào nhau
Hai phần này nên đọc cạnh nhau là thấy ngay khác biệt.
Expected Result
User is redirected to
/dashboardand the account overview is displayed.
Actual Result
User remains on
/login. The button stops showing the loading state after about two seconds and no error message is displayed.
Actual là thứ mình quan sát được, không phải phán đoán nguyên nhân.
API login bị lỗi nên UI không redirect.
Câu này có thể đúng, nhưng nếu chưa xem network hoặc log thì nó vẫn là đoán. Viết POST /api/login returned 500 khi đã có bằng chứng sẽ chắc hơn. Còn nếu chỉ thấy UI đứng im thì cứ mô tả UI đứng im.
Dev cần chỗ bắt đầu để điều tra, không cần tester bói backend.
Evidence: ảnh, video hay log?
UI lệch một cục và nằm im tại chỗ thì ảnh là đủ. Một menu mở lên rồi tự đóng, animation giật hoặc lỗi chỉ xuất hiện trong hai giây thì quay video. API, console error hay performance issue thì thêm log, HAR hoặc response liên quan.
Evidence tốt nên cho thấy:
- Người test đang ở đâu.
- Vừa làm hành động gì.
- Failure xuất hiện thế nào.
- Thời gian hoặc request ID nếu cần tra log phía server.
Chụp đúng một popup Something went wrong rồi crop sạch URL, thời gian và thao tác trước đó thì ảnh rất nét nhưng thông tin vẫn bằng không.
Với video cũng vậy. Cắt đoạn chờ hai phút đầu, nhưng đừng cắt mất precondition làm bug xuất hiện.
Severity và Priority
Severity là mức ảnh hưởng. Priority là mức cần sửa gấp. Hai cái liên quan nhưng không phải một.
Bug không đăng nhập được bằng mọi tài khoản gần như chắc chắn Severity cao và Priority cao. Nhưng một lỗi crash chỉ xảy ra trong trang admin mỗi năm dùng một lần có thể Severity cao mà Priority hiện tại thấp hơn. Banner chiến dịch bị sai logo không hỏng chức năng, Severity thấp, nhưng sáng mai chạy quảng cáo thì Priority có thể nhảy lên đầu.
Tester có thể đề xuất cả hai, nhưng tuỳ quy trình, Priority thường cần Product Owner, BA hoặc người chịu trách nhiệm business cùng quyết định. Đừng biến buổi defect triage thành cuộc thi xem ai nói to hơn.
Một bug report hoàn chỉnh
Ghép lại ví dụ đầu bài:
| Trường | Nội dung |
|---|---|
| Title | [Login] User remains on Login page after submitting a valid admin account |
| Environment | Test · build 2026.08.09-rc2 · Chrome 139 · Windows 11 |
| Precondition | Account admin_01 is active and has the Admin role |
| Steps | 1. Open /login 2. Enter valid credentials 3. Click Login |
| Expected | User is redirected to /dashboard and account overview is displayed |
| Actual | User remains on /login; loading ends after about two seconds; no error message appears |
| Reproducibility | 5/5 |
| Evidence | Video, network response and request ID attached |
| Severity | High — blocks the main flow for an active account |
Người nhận report này vẫn phải debug, đương nhiên. Nhưng họ không phải quay lại hỏi tester bug nằm ở đâu và chạy kiểu gì.
Ghi để cùng sửa
Bug report là một sản phẩm làm việc, không phải biên bản xác nhận ai vừa phạm tội. Các câu kiểu “dev code sai”, “basic case cũng fail” hoặc tag nửa công ty vào để tăng áp lực không làm defect biến mất nhanh hơn.
Viết đúng điều mình đã quan sát, đưa đủ bằng chứng và phản hồi khi người sửa cần thêm thông tin. Nếu dev không reproduce được thì hai bên mở cùng build, cùng data rồi nhìn lại. Có thể report thiếu, cũng có thể môi trường khác nhau, hoặc defect vừa bị một thay đổi khác che mất.
Mục tiêu cuối cùng rất đơn giản: người tiếp theo đọc bug xong biết phải chạy gì, nhìn gì và tại sao việc sửa nó đáng được ưu tiên. Làm được thế thì dev muốn sửa hay không chưa biết, nhưng ít nhất họ không phải sửa trong trạng thái đoán mò.