Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bug Reporting chuẩn — Severity vs Priority

Software Testing Fundamentals Bài 27/60

Mở đầu — vì sao bài này quan trọng

Trong nghề QA, một trong những kỹ năng "tưởng dễ mà khó" chính là viết bug report. Nhiều bạn tester mới vào nghề nghĩ rằng chỉ cần thấy lỗi, chụp màn hình rồi ghi vài dòng "bị lỗi rồi nha anh dev" là xong. Nhưng thực tế, một bug report tồi có thể khiến developer mất cả buổi để đoán xem "lỗi gì, ở đâu, làm sao tái hiện", còn team lead thì không biết nên sửa cái nào trước. Ngược lại, một bug report chuẩn giúp cả team ra quyết định nhanh, sửa đúng, và quan trọng nhất là không để lọt lỗi nghiêm trọng ra production.

Ở trung tâm của một bug report chuyên nghiệp là hai khái niệm mà rất nhiều người — kể cả tester có kinh nghiệm — hay nhầm lẫn: Severity (mức nghiêm trọng) và Priority (mức ưu tiên). Hai khái niệm này nghe qua thì na ná nhau, nhưng bản chất hoàn toàn khác. Hiểu sai chúng dẫn tới hậu quả rất thật: lỗi chính tả trên logo công ty được xử lý sau lỗi crash chỉ vì "crash nghe có vẻ nghiêm trọng hơn", hoặc ngược lại — dev cắm đầu sửa một lỗi hiếm gặp trong khi cả nghìn khách hàng đang không thanh toán được.

Bài này sẽ giúp bạn nắm vững cách viết một bug report chuẩn, và đặc biệt là phân biệt rạch ròi Severity với Priority — nền tảng để bạn giao tiếp chuyên nghiệp với cả dev, PM lẫn khách hàng.

Khái niệm cốt lõi

Bug report chuẩn gồm những gì?

Trước khi bàn tới Severity và Priority, hãy nhớ rằng chúng chỉ là hai trường trong một bug report hoàn chỉnh. Một bug report chuẩn thường gồm:

  • Title (tiêu đề): ngắn gọn, mô tả đúng vấn đề. Công thức tốt: [Màn hình/Chức năng] — Hành vi lỗi khi điều kiện gì. Ví dụ: "Trang thanh toán — Nút 'Đặt hàng' không phản hồi khi chọn MoMo trên Safari".
  • Environment (môi trường): trình duyệt, hệ điều hành, thiết bị, phiên bản app, môi trường (dev/staging/production).
  • Preconditions (điều kiện tiền đề): trạng thái cần có trước khi tái hiện (ví dụ: đã đăng nhập, giỏ hàng có ít nhất 1 sản phẩm).
  • Steps to reproduce (các bước tái hiện): đánh số rõ ràng 1, 2, 3 để dev làm theo đúng.
  • Expected result (kết quả mong đợi): đúng ra phải xảy ra gì.
  • Actual result (kết quả thực tế): thực tế xảy ra gì.
  • Attachments (bằng chứng): ảnh chụp màn hình, video, log, request/response.
  • Severity và Priority: hai trường phân loại — chủ đề chính của bài này.

Severity — mức nghiêm trọng về mặt kỹ thuật

Severity trả lời câu hỏi: "Lỗi này gây thiệt hại/ảnh hưởng đến hệ thống nghiêm trọng tới mức nào?" Đây là góc nhìn kỹ thuật, khách quan, do tester đánh giá dựa trên tác động của lỗi lên chức năng và dữ liệu. Severity không quan tâm tới lịch phát hành, chiến lược kinh doanh hay khách hàng nào đang chờ.

Thang phân loại phổ biến (4 mức):

LevelĐịnh nghĩaVí dụ thực tế
S1 — CriticalỨng dụng không dùng được, sập hệ thống, mất dữ liệu, không có cách workaroundApp crash ngay khi mở; toàn bộ user không đăng nhập được; đơn hàng bị trừ tiền nhưng không ghi nhận
S2 — MajorChức năng chính hỏng nhưng hệ thống vẫn chạy, hoặc có workaround khó chịuKhông thêm được sản phẩm vào giỏ bằng nút, phải vào trang chi tiết mới thêm được; xuất báo cáo bị sai số liệu
S3 — MinorChức năng phụ lỗi, ảnh hưởng nhỏ tới trải nghiệmBộ lọc "Sắp xếp theo giá" hiển thị sai thứ tự ở vài trường hợp; thông báo lỗi hiển thị chưa thân thiện
S4 — Trivial / CosmeticLỗi hình thức, không ảnh hưởng chức năngSai chính tả, lệch 2px, màu nút không đúng thiết kế
Điểm mấu chốt: Severity đo mức độ hỏng về mặt chức năng/kỹ thuật. Một lỗi làm sập cả hệ thống luôn là S1, bất kể nó xảy ra ở màn hình ít người dùng.

Priority — mức ưu tiên xử lý

Priority trả lời câu hỏi: "Lỗi này cần được sửa gấp tới mức nào?" Đây là góc nhìn kinh doanh/dự án, thường do PM, Product Owner hoặc team lead quyết định (tester đề xuất). Priority cân nhắc: lịch release, số lượng khách hàng bị ảnh hưởng, hình ảnh thương hiệu, ràng buộc hợp đồng, thời điểm.

Thang phân loại phổ biến:

LevelÝ nghĩa
P1 — High/UrgentPhải sửa ngay, chặn release hoặc đang gây thiệt hại trên production
P2 — MediumNên sửa trong sprint/bản phát hành hiện tại
P3 — LowSửa khi có thời gian, có thể để backlog

Vì sao Severity và Priority độc lập với nhau

Đây là ý quan trọng nhất của bài. Hai trục này độc lập, nên có đủ 4 tổ hợp:

  • Severity cao — Priority cao: App crash khi bấm "Thanh toán" trên trang chủ. Vừa nghiêm trọng kỹ thuật, vừa cấp bách kinh doanh → sửa ngay.
  • Severity cao — Priority thấp: Chức năng "Xuất hóa đơn PDF" crash hoàn toàn (S1), nhưng tính năng này mới chỉ 0,1% khách dùng và sẽ được thay bằng module mới tháng sau → Priority thấp.
  • Severity thấp — Priority cao: Tên công ty bị viết sai chính tả ngay trên trang chủ, hoặc logo đối tác lớn bị hiển thị sai. Về kỹ thuật chỉ là lỗi cosmetic (S4), nhưng ảnh hưởng thương hiệu nghiêm trọng, sếp yêu cầu sửa trong 1 giờ → Priority cao.
  • Severity thấp — Priority thấp: Lệch 3px ở footer trang "Điều khoản" → để backlog.
Nhớ câu thần chú: Severity là "hỏng nặng cỡ nào" (tester quyết), Priority là "sửa gấp cỡ nào" (business quyết).

Tình huống thực tế

Tình huống 1 — Lỗi chính tả trên banner Tết của Tiki

Cận Tết Nguyên đán, một sàn thương mại điện tử kiểu Tiki tung chiến dịch "Sắm Tết — Giảm đến 50%". Bạn Linh, tester trong team, phát hiện banner lớn ở trang chủ ghi nhầm thành "Giảm đến 5%" — thiếu số 0. Về mặt kỹ thuật, đây chỉ là lỗi nội dung, không có gì crash, không mất dữ liệu → Severity: S4 (Cosmetic).

Nhưng bối cảnh là banner này đã lên production, hiển thị cho hàng trăm nghìn lượt truy cập mỗi giờ trong mùa cao điểm, và làm hiểu sai chương trình khuyến mãi — có thể dẫn tới khiếu nại và mất uy tín. Linh đề xuất Priority: P1 (Urgent). PM đồng ý, và dev sửa nội dung, deploy hotfix trong vòng 20 phút.

Bài học: Một lỗi Severity thấp nhất vẫn có thể là Priority cao nhất. Nếu Linh chỉ nhìn Severity mà gắn P3, lỗi này sẽ nằm chờ trong backlog trong khi thiệt hại thương hiệu tăng theo từng phút. Đây là ví dụ kinh điển cho việc đừng gắn Priority bằng cách sao chép Severity.

Tình huống 2 — Ví MoMo lỗi ở luồng thanh toán của một app đặt đồ ăn

Một startup giao đồ ăn tại TP.HCM tích hợp cổng thanh toán MoMo. Trong đợt kiểm thử regression trước bản phát hành, tester Hùng phát hiện: khi khách chọn thanh toán bằng MoMo và app ở trạng thái mạng 3G yếu, giao dịch đôi khi bị trừ tiền trong ví nhưng đơn hàng lại báo "Thanh toán thất bại". Tiền đã ra khỏi ví khách nhưng hệ thống không ghi nhận đơn.

Hùng đánh giá đây là lỗi liên quan tới mất/không nhất quán dữ liệu tài chính — nghiêm trọng nhất về kỹ thuật → Severity: S1 (Critical). Về Priority, vì đây là luồng thanh toán cốt lõi, ảnh hưởng trực tiếp tới tiền của khách và niềm tin, dù chỉ xảy ra ~2% giao dịch trên mạng yếu → Priority: P1.

Điều đáng chú ý là cách Hùng viết report: anh không chỉ ghi "lỗi thanh toán MoMo". Anh đính kèm mã giao dịch (transaction ID) từ log MoMo, timestamp, ảnh chụp màn hình cả hai phía (ví MoMo báo trừ tiền, app báo thất bại), và mô tả rõ điều kiện tái hiện là "giả lập mạng 3G, độ trễ > 3 giây". Nhờ vậy dev tái hiện được ngay và tìm ra nguyên nhân là callback bị timeout mà không có cơ chế đối soát.

Bài học: Với lỗi tài chính, luôn nghĩ tới S1. Và một bug report tốt về thanh toán bắt buộc phải có transaction ID + bằng chứng hai phía, nếu không dev sẽ không tin và không tái hiện được.

Tình huống 3 — Báo cáo doanh thu sai số nhưng để đến sprint sau

Một công ty SaaS quản lý bán hàng phục vụ các cửa hàng nhỏ ở Đông Nam Á. Tester Mai phát hiện module "Báo cáo doanh thu theo tháng" tính sai khi tháng có ngày nhuận đặc biệt — con số lệch khoảng 3%. Đây là chức năng quan trọng, số liệu sai → Severity: S2 (Major).

Tuy nhiên khi đưa lên bug triage, PM cân nhắc: lỗi chỉ xảy ra với tháng 2 năm nhuận (rất hiếm), báo cáo hiện tại đang giữa tháng 6, và team đang dồn lực cho tính năng lớn sắp demo với nhà đầu tư vào cuối sprint. PM quyết định Priority: P3, đưa vào backlog để sửa ở sprint sau kèm test kỹ.

Bài học: Severity S2 không tự động thành Priority cao. Quyết định Priority thuộc về business, dựa trên tần suất, thời điểm và bối cảnh dự án. Vai trò của Mai là đề xuất Priority và nêu rõ tác động để PM ra quyết định đúng — chứ không phải tự ý hạ Severity xuống cho "khớp" với Priority. Severity vẫn giữ S2 để phản ánh đúng bản chất kỹ thuật.

Hướng dẫn từng bước

Khi phát hiện một lỗi, hãy đi theo quy trình sau để tạo bug report chuẩn và gắn Severity/Priority hợp lý:

  • Tái hiện lại lỗi ít nhất 2 lần. Xác nhận đây là lỗi thật, không phải do thao tác nhầm hay cache. Ghi lại chính xác các bước.
  • Viết Title theo công thức. [Chức năng/Màn hình] — hành vi lỗi + điều kiện. Tránh tiêu đề mơ hồ như "Bị lỗi" hay "Không chạy được".
  • Ghi đầy đủ Environment và Preconditions. Nêu rõ trình duyệt/thiết bị/phiên bản. Nhiều lỗi chỉ xuất hiện trên một cấu hình cụ thể.
  • Viết Steps to reproduce đánh số. Mỗi bước một hành động rõ ràng, để bất kỳ ai cũng làm theo được.
  • Ghi rõ Expected vs Actual. Đây là phần chứng minh "đây thực sự là bug", không phải tính năng như thiết kế.
  • Đính kèm bằng chứng. Ảnh, video, log, transaction ID. Với lỗi khó tái hiện, video là vàng.
  • Đánh giá Severity — hỏi: "Lỗi này phá hoại chức năng/dữ liệu tới đâu?" Dùng thang S1–S4. Chỉ nhìn tác động kỹ thuật, gạt bỏ yếu tố "ai đang chờ", "sắp release chưa".
  • Đề xuất Priority — hỏi: "Xét bối cảnh kinh doanh, cần sửa gấp tới đâu?" Cân nhắc số khách bị ảnh hưởng, môi trường (production hay staging), thời điểm release, thương hiệu, hợp đồng.
  • Ghi kèm lý do đề xuất Priority. Ví dụ: "Đề xuất P1 vì đang xảy ra trên production, ảnh hưởng ~800 giao dịch/ngày". Lý do rõ giúp buổi bug triage nhanh và ít cãi nhau.
  • Gán assignee/label và submit. Tuân theo quy ước công cụ của team (Jira, Redmine, Azure DevOps...).

Lỗi thường gặp & mẹo

Lỗi 1 — Đánh đồng Severity với Priority. Đây là lỗi phổ biến nhất. Nhiều tester copy y nguyên: S1 thì P1, S4 thì P3. Hệ quả là những lỗi cosmetic ảnh hưởng thương hiệu bị bỏ quên, còn lỗi S1 ở tính năng không ai dùng lại chiếm chỗ của dev. Hãy luôn đánh giá hai trục tách biệt.

Lỗi 2 — Title mơ hồ. "App bị lỗi", "Trang không load". Dev và PM lướt qua danh sách bug không biết là gì, khó ưu tiên. Title phải đủ để hiểu vấn đề mà không cần mở chi tiết.

Lỗi 3 — Thiếu bước tái hiện hoặc bước không đầy đủ. Nếu dev không tái hiện được, bug thường bị đóng với trạng thái "Cannot reproduce" và quay lại làm phiền bạn. Luôn kiểm tra: người khác đọc steps của mình có làm được không?

Lỗi 4 — Tester tự ý nâng/hạ Priority theo cảm tính. Priority là quyết định của business. Tester đề xuấtcung cấp dữ liệu tác động, nhưng quyết định cuối thường ở PM/triage. Đừng tự ý gán P1 cho mọi lỗi mình tìm ra chỉ vì "mình thấy nó quan trọng".

Lỗi 5 — Đưa nhiều lỗi vào một report. Mỗi bug một report. Gộp chung khiến việc theo dõi trạng thái sửa từng lỗi trở nên rối loạn.

Mẹo:

  • Với lỗi tài chính, mất dữ liệu, bảo mật, mặc định nghĩ tới S1 trước, rồi mới cân nhắc hạ nếu có lý do.
  • Khi phân vân Severity, hãy tự hỏi: "Có workaround không?" Có workaround dễ → thường hạ một bậc.
  • Khi đề xuất Priority, luôn kèm con số: bao nhiêu user, bao nhiêu giao dịch, môi trường nào. Con số thuyết phục hơn cảm tính.
  • Chuẩn hóa định nghĩa S1–S4 và P1–P3 thành tài liệu chung của team, dán ngay trong công cụ bug tracking để mọi người hiểu giống nhau.

Bài tập thực hành

Bài 1 — Phân loại Severity và Priority. Với mỗi tình huống dưới đây, hãy gán Severity (S1–S4) và Priority (P1–P3), kèm một câu giải thích:

a) Toàn bộ khách hàng không đăng nhập được vào app ngân hàng số vào 9h sáng thứ Hai. b) Nút "Chia sẻ Facebook" trên trang blog nội bộ (chỉ nhân viên xem) không hoạt động. c) Tên thương hiệu bị viết sai trên trang landing page của chiến dịch quảng cáo đang chạy. d) Chức năng xuất file Excel của module thống kê bị lỗi, nhưng có thể xuất tạm qua CSV.

Bài 2 — Sửa một bug report tồi. Cho report sau, hãy viết lại cho chuẩn: "Title: Lỗi thanh toán. Mô tả: thanh toán bị lỗi, không được. Severity: cao." Hãy bổ sung Title chuẩn, Steps to reproduce giả định, Expected/Actual, Environment, và đề xuất Severity + Priority kèm lý do.

Bài 3 — Viết định nghĩa cho team. Giả sử bạn là QA lead của một app đặt vé xe khách VN. Hãy soạn bảng định nghĩa 4 mức Severity (S1–S4), mỗi mức cho một ví dụ đặc thù của nghiệp vụ đặt vé (ví dụ liên quan chọn ghế, thanh toán, xuất vé, hiển thị lịch trình).

Gợi ý đáp án Bài 1: (a) S1/P1; (b) S2 về chức năng nhưng phạm vi hẹp, P3; (c) S4 nhưng P1 do ảnh hưởng thương hiệu và đang chạy quảng cáo; (d) S2 nhưng vì có workaround CSV nên có thể P2/P3.

Tóm tắt

  • Một bug report chuẩn gồm: Title rõ ràng, Environment, Preconditions, Steps to reproduce, Expected/Actual result, bằng chứng đính kèm, và hai trường phân loại Severity + Priority.
  • Severity = mức nghiêm trọng kỹ thuật của lỗi ("hỏng nặng cỡ nào"), do tester đánh giá khách quan theo thang S1 (Critical) → S4 (Trivial). Chỉ quan tâm tác động lên chức năng và dữ liệu.
  • Priority = mức cấp bách cần sửa ("gấp cỡ nào"), do business/PM quyết định theo thang P1 → P3, dựa trên số khách bị ảnh hưởng, thương hiệu, lịch release và bối cảnh.
  • Hai trục độc lập với nhau: tồn tại đủ 4 tổ hợp, kể cả "Severity thấp — Priority cao" (lỗi chính tả banner Tết) và "Severity cao — Priority thấp" (tính năng crash nhưng sắp bỏ).
  • Đừng bao giờ copy Priority từ Severity. Với lỗi tài chính/dữ liệu/bảo mật, mặc định nghĩ S1. Khi đề xuất Priority, luôn kèm con số tác động.
  • Vai trò của tester: đánh giá Severity chính xác, đề xuất Priority kèm dữ liệu, và viết report đủ rõ để dev tái hiện ngay lần đầu.