Mở đầu — vì sao bài này quan trọng
Trong suốt các bài trước, bạn đã học rất nhiều kỹ thuật kiểm thử "chính quy" (formal): Equivalence Partitioning, Boundary Value Analysis, Decision Table, State Transition... Những kỹ thuật này tuyệt vời vì chúng có công thức, có thể dạy được, có thể kiểm chứng độ bao phủ. Nhưng có một sự thật mà bất kỳ tester giàu kinh nghiệm nào cũng thừa nhận: phần lớn những bug nghiêm trọng nhất trong sự nghiệp của họ được tìm ra không phải bằng test case viết sẵn, mà bằng trực giác và sự tò mò.
Đó chính là lãnh địa của hai kỹ thuật trong bài này: Error Guessing (đoán lỗi dựa trên kinh nghiệm) và Exploratory Testing (kiểm thử thăm dò). Cả hai đều là kiểm thử "phi chính quy" (informal) — không dựa vào tài liệu đặc tả cứng nhắc, mà dựa vào bộ não, kinh nghiệm và khả năng phán đoán của con người.
Vì sao bài này quan trọng đến vậy? Vì trong thực tế, bạn sẽ luôn thiếu thời gian, thiếu tài liệu đặc tả đầy đủ, và requirement thì thay đổi liên tục. Nếu chỉ biết chờ có test case hoàn chỉnh mới dám test, bạn sẽ luôn chậm chân. Ngược lại, một tester biết "đánh hơi" chỗ nào dễ sai, biết ngồi xuống và khám phá sản phẩm một cách có kỷ luật, sẽ tạo ra giá trị ngay từ ngày đầu tiên. Đây cũng chính là kỹ năng phân biệt một tester "bấm nút theo kịch bản" với một tester thực sự nghĩ như một kẻ phá hoại thông minh.
Khái niệm cốt lõi
Error Guessing là gì?
Error Guessing là kỹ thuật kiểm thử trong đó tester dựa vào kinh nghiệm, trực giác và hiểu biết về những lỗi lập trình phổ biến để đoán ra những chỗ mà hệ thống có khả năng cao bị lỗi, rồi thiết kế test case nhắm thẳng vào những chỗ đó.
Nó không phải là đoán mò kiểu "hên xui". Nó là suy luận có căn cứ. Một tester giỏi biết rằng:
- Chỗ nào có xử lý số 0, số âm, số rất lớn → dev hay quên.
- Chỗ nào có input rỗng (empty), null, khoảng trắng (space) → dev hay không handle.
- Chỗ nào có ngày tháng, múi giờ, năm nhuận → luôn tiềm ẩn bug.
- Chỗ nào upload file → thử file 0 byte, file sai định dạng đổi đuôi, file tên có ký tự đặc biệt.
- Chỗ nào có tính tiền, làm tròn → thử số lẻ như 0.1 + 0.2.
- Chỗ nào có tiếng Việt có dấu → thử tìm kiếm, sắp xếp, hiển thị.
Fault Attack — phiên bản có hệ thống của Error Guessing
Để Error Guessing không quá lệ thuộc vào một cá nhân, người ta hệ thống hóa nó thành danh sách các loại lỗi thường gặp (defect taxonomy) hay còn gọi là fault attack. Ví dụ, mỗi khi gặp một trường nhập liệu, tester sẽ chạy qua một "checklist tấn công" cố định:
- Bỏ trống → có bắt buộc không?
- Nhập tối đa + 1 ký tự → có tràn không?
- Nhập ký tự đặc biệt, emoji, SQL injection cơ bản
' OR 1=1. - Nhập khoảng trắng ở đầu/cuối → có trim không?
- Copy-paste một đoạn text 10.000 ký tự.
Exploratory Testing là gì?
Exploratory Testing (kiểm thử thăm dò) là cách tiếp cận trong đó việc thiết kế test, thực thi test và học về sản phẩm diễn ra đồng thời. Bạn không viết trước 100 test case rồi mới chạy. Thay vào đó, bạn tương tác trực tiếp với sản phẩm, quan sát kết quả, và kết quả mỗi bước sẽ định hướng bước tiếp theo.
Cụm từ kinh điển của Cem Kaner (người đặt ra thuật ngữ này) là: exploratory testing là "simultaneous learning, test design, and test execution" — học, thiết kế và thực thi cùng một lúc.
Điểm mấu chốt cần nhớ: Exploratory Testing KHÔNG phải là "test bừa" (ad-hoc) không có định hướng. Nó là kiểm thử có kỷ luật, có mục tiêu, nhưng linh hoạt về đường đi. Sự khác biệt nằm ở chỗ: ad-hoc là bấm loạn xạ không ghi chép; exploratory là có charter (nhiệm vụ), có ghi chú, có thời lượng.
Session-Based Test Management (SBTM)
Để quản lý exploratory testing một cách chuyên nghiệp, ngành QA dùng mô hình Session-Based Test Management do James Bach và Jonathan Bach phát triển. Ý tưởng:
- Chia công việc thành các session (phiên) kéo dài 60–120 phút, không bị gián đoạn.
- Mỗi session có một charter — một câu mô tả ngắn về mục tiêu, ví dụ: "Khám phá chức năng thanh toán bằng ví MoMo, tập trung vào các trường hợp huỷ giữa chừng và mất mạng."
- Trong session, tester ghi lại (notes): đã test gì, thấy gì, nghi ngờ gì, bug nào, câu hỏi nào.
- Sau session có phần debrief — trao đổi nhanh với lead về kết quả.
Error Guessing vs Exploratory Testing — chúng khác nhau thế nào?
Nhiều người nhầm hai khái niệm. Hãy phân biệt rõ:
- Error Guessing là một kỹ thuật thiết kế test — nó trả lời câu hỏi "test cái gì?". Nó nhắm vào những điểm nghi ngờ cụ thể dựa trên kinh nghiệm.
- Exploratory Testing là một cách tiếp cận / phong cách làm việc — nó trả lời câu hỏi "test như thế nào?". Nó là cả một quá trình học và khám phá.
Tình huống thực tế
Ví dụ 1 — Sàn TMĐT và cái giỏ hàng "âm tiền"
Một sàn thương mại điện tử lớn tại Việt Nam (giả định tên ShopViet) chuẩn bị tung chương trình flash sale 12/12. Đội QA có 3 người, requirement gửi trễ, chỉ còn 2 ngày trước khi go-live. Không kịp viết test case đầy đủ cho toàn bộ luồng khuyến mãi.
Chị Lan, QA lead, quyết định chạy một session exploratory 90 phút với charter: "Khám phá tương tác giữa mã giảm giá, freeship và điểm thưởng khi áp dụng đồng thời." Dựa trên error guessing, chị nhắm ngay vào chỗ dễ sai nhất: cộng dồn nhiều loại giảm giá.
Chị thử: đơn hàng 200.000đ, áp mã giảm 50%, cộng thêm voucher freeship 30.000đ, cộng thêm 15.000 điểm thưởng. Kết quả: tổng thanh toán hiển thị âm 5.000đ. Hệ thống không chặn khi tổng giảm giá vượt quá giá trị đơn hàng. Nếu lên production, kẻ xấu có thể "mua hàng mà được trả tiền".
Bài học: Error guessing đã chỉ đúng vào điểm chí mạng (chỗ cộng dồn nhiều discount) mà không cần bất kỳ test case chính quy nào. Exploratory testing cho phép phát hiện bug này trong vòng 20 phút — điều mà việc chờ đợi tài liệu đặc tả hoàn chỉnh sẽ không bao giờ kịp.
Ví dụ 2 — App gọi xe và bug "múi giờ" lúc nửa đêm
Một startup gọi xe ở Đông Nam Á (giả định GoRide) nhận phản ánh rằng một số chuyến đi lúc gần nửa đêm bị tính sai giá — có chuyến bị tính phụ phí ban đêm gấp đôi, có chuyến lẽ ra có phụ phí thì lại không.
Đội QA ban đầu không hiểu vì test case regression đều pass. Một tester senior tên Minh áp dụng error guessing: "Cứ dính đến thời gian, ngày tháng, múi giờ là 90% có bug." Anh mở một session exploratory nhắm vào các mốc thời gian nhạy cảm: 23:59, 00:00, 00:01, và đặc biệt là thời điểm chuyển ngày khi server chạy giờ UTC còn app hiển thị giờ Việt Nam (UTC+7).
Bug lộ ra: server lưu thời gian đặt chuyến bằng UTC, nhưng logic tính phụ phí ban đêm (22h–6h) lại so sánh với giờ UTC thay vì giờ địa phương. Một chuyến đặt lúc 23:30 giờ Việt Nam (tức 16:30 UTC) bị hệ thống coi là ban ngày.
Bài học: Không một test case viết sẵn nào bắt được bug này vì người viết test case cũng có cùng "điểm mù" như dev. Chỉ có tester chủ động error guessing vào vùng thời gian và tự do khám phá mới lật được nó ra. Đây là minh chứng cho Nghịch lý thuốc trừ sâu: test case lặp lại mãi sẽ không tìm ra bug mới, cần con người tư duy để bù đắp.
Ví dụ 3 — Ngân hàng số và ô tìm kiếm tên tiếng Việt
Một ngân hàng số (giả định VietBank Digital) ra mắt tính năng chuyển tiền theo danh bạ. QA junior tên Trang được giao test ô tìm kiếm người nhận. Test case chính quy chỉ yêu cầu: "nhập tên, hiển thị đúng kết quả". Tất cả pass.
Nhưng Trang mới học error guessing, cô tự hỏi: "Tiếng Việt có dấu thì sao? Chữ hoa chữ thường thì sao? Tên có khoảng trắng thừa thì sao?" Cô mở một session 60 phút và thử: tìm "Đức" (có dấu), "duc" (không dấu), "ĐỨC" (hoa), " Đức " (có space thừa).
Kết quả: tìm "Đức" ra đúng, nhưng tìm "duc" không ra gì cả — hệ thống không hỗ trợ tìm kiếm không dấu, trong khi phần lớn người Việt gõ nhanh thường bỏ dấu. Ngoài ra, khoảng trắng thừa cũng làm search fail hoàn toàn.
Bài học: Đây không phải bug làm sập hệ thống, nhưng là bug ảnh hưởng nghiêm trọng tới trải nghiệm của hàng triệu người dùng Việt. Nó chỉ được tìm ra vì tester áp dụng error guessing đúng vào đặc thù ngôn ngữ địa phương — thứ mà đặc tả gốc (thường viết bằng tư duy tiếng Anh) bỏ sót.
Hướng dẫn từng bước
Dưới đây là quy trình thực hành để bạn chạy một buổi Error Guessing kết hợp Exploratory Testing một cách chuyên nghiệp.
Bước 1 — Xác định charter (nhiệm vụ). Đừng ngồi xuống rồi "test đại". Hãy viết một câu charter rõ ràng: "Khám phá [khu vực nào], tập trung vào [rủi ro gì], sử dụng [dữ liệu/công cụ gì]." Charter càng cụ thể, session càng có giá trị.
Bước 2 — Chuẩn bị "danh sách tấn công" (fault list). Trước khi vào session, liệt kê nhanh các loại lỗi bạn nghi ngờ dựa trên kinh nghiệm: input rỗng, boundary, ký tự đặc biệt, tiếng Việt có dấu, thời gian/múi giờ, mất mạng giữa chừng, thao tác đồng thời (race condition), nhấn nút hai lần (double click)...
Bước 3 — Đặt giới hạn thời gian (timebox). Chọn 60–90 phút. Tắt Slack, Zalo, thông báo. Sự tập trung không gián đoạn là điều kiện sống còn của exploratory testing.
Bước 4 — Khám phá và ghi chú song song. Vừa thao tác vừa ghi lại: bạn đã thử gì, kết quả ra sao, chỗ nào thấy "kỳ kỳ". Đừng bỏ qua trực giác — khi thấy điều gì đó "hơi sai sai", hãy dừng lại và đào sâu.
Bước 5 — Bám theo dấu vết (follow the scent). Mỗi khi phát hiện một điều bất thường, đừng vội đi tiếp. Hãy dùng error guessing để tấn công dồn dập vào khu vực đó với các biến thể khác nhau. Một bug nhỏ thường là dấu hiệu của một cụm bug lớn hơn.
Bước 6 — Ghi nhận bug ngay lập tức. Chụp màn hình, ghi lại các bước tái hiện. Trong exploratory testing rất dễ quên mình đã làm gì để tạo ra bug, nên phải ghi ngay.
Bước 7 — Debrief. Sau session, tóm tắt lại cho lead/team: đã khám phá được gì, tìm ra bug gì, còn vùng nào đáng nghi cần session tiếp theo.
Lỗi thường gặp & mẹo
Lỗi 1 — Nhầm exploratory testing với "test không cần suy nghĩ". Nhiều bạn tưởng exploratory là bấm loạn cho vui. Sai hoàn toàn. Không có charter, không ghi chú thì đó chỉ là ad-hoc vô kỷ luật. Mẹo: luôn bắt đầu bằng một câu charter viết ra giấy.
Lỗi 2 — Không ghi lại bước tái hiện. Tìm ra bug xịn nhưng không nhớ mình bấm gì để ra nó → dev không tái hiện được → bug bị close "Cannot reproduce". Mẹo: bật màn hình quay video (screen recording) trong suốt session, hoặc dùng tool như Azure Test Plans / Jam để tự lưu vết.
Lỗi 3 — Chỉ dựa vào error guessing mà bỏ hết test chính quy. Error guessing rất mạnh nhưng phụ thuộc con người và không đo được độ bao phủ. Nó là bổ sung, không thay thế cho EP, BVA hay decision table. Mẹo: dùng test chính quy làm nền, error guessing làm lớp "gia vị" đánh vào chỗ đặc tả bỏ sót.
Lỗi 4 — Cho rằng đây là kỹ thuật của người mới. Ngược lại, error guessing hiệu quả nhất khi tester càng nhiều kinh nghiệm, càng "bị bug cắn" nhiều lần. Junior nên chủ động xây một fault checklist cá nhân và bồi đắp nó sau mỗi dự án.
Lỗi 5 — Không đặt timebox. Không giới hạn thời gian thì session dễ lan man vô tận hoặc bị công việc khác cắt ngang. Mẹo: 90 phút là con số vàng — đủ dài để đào sâu, đủ ngắn để giữ tập trung.
Mẹo vàng — Nuôi dưỡng "khứu giác bug". Sau mỗi bug production lọt lưới, hãy tự hỏi: "Lẽ ra mình phải đoán được chỗ này ở đâu?" rồi thêm nó vào fault list. Đây chính là cách bạn biến kinh nghiệm đau thương thành trực giác sắc bén — thứ tài sản quý nhất của một tester giỏi.
Bài tập thực hành
Bài tập 1 — Xây fault checklist cá nhân. Hãy tự liệt kê 15 loại "điểm dễ sai" mà bạn nghĩ dev hay mắc phải (gợi ý: input, thời gian, tiền bạc, ngôn ngữ, mạng, đồng thời...). Với mỗi loại, viết một câu ví dụ cụ thể về cách tấn công nó. Lưu lại làm tài liệu dùng suốt sự nghiệp.
Bài tập 2 — Chạy một session thật. Chọn một ứng dụng bạn hay dùng (ví dụ app ngân hàng, app đặt đồ ăn, hoặc chính website khóa học này). Viết một charter cụ thể, đặt timebox 60 phút, chạy exploratory testing thật sự và ghi chú đầy đủ. Cuối buổi, đếm xem bạn tìm được bao nhiêu vấn đề (dù nhỏ như lỗi hiển thị, chính tả, UX khó chịu).
Bài tập 3 — Error guessing cho ô nhập số tiền. Cho một ô "Nhập số tiền chuyển khoản". Hãy dùng error guessing để liệt kê ít nhất 12 giá trị bạn sẽ thử (gợi ý: 0, số âm, số thập phân, số cực lớn, để trống, ký tự chữ, dấu phẩy/chấm ngăn cách, khoảng trắng, dán 10.000 chữ số...). Với mỗi giá trị, ghi rõ bạn kỳ vọng hệ thống phản ứng thế nào.
Bài tập 4 — Phân tích một bug đã gặp. Nhớ lại (hoặc tìm trên mạng) một bug nổi tiếng. Hãy trả lời: nếu là bạn, error guessing nào lẽ ra đã bắt được nó? Viết charter mà bạn sẽ dùng để săn con bug đó.
Tóm tắt
Error Guessing và Exploratory Testing là hai kỹ thuật kiểm thử phi chính quy nhưng cực kỳ hiệu quả, bổ trợ hoàn hảo cho các kỹ thuật thiết kế test chính quy.
- Error Guessing là kỹ thuật thiết kế test dựa trên kinh nghiệm và trực giác để nhắm vào những chỗ hệ thống dễ sai. Nó trả lời câu hỏi "test cái gì?".
- Exploratory Testing là cách tiếp cận trong đó học, thiết kế và thực thi test diễn ra đồng thời. Nó có kỷ luật — dùng charter, timebox và ghi chú — chứ không phải test bừa. Nó trả lời câu hỏi "test như thế nào?".
- Session-Based Test Management (SBTM) giúp quản lý và đo lường exploratory testing thông qua session và charter thay vì đếm test case.
- Trong thực tế, hai kỹ thuật đi cùng nhau: bạn khám phá tự do, và khi "ngửi thấy mùi bug", bạn dùng error guessing để tấn công dồn dập.
- Chúng đặc biệt mạnh với các đặc thù Việt Nam: tiếng Việt có dấu/không dấu, múi giờ UTC+7, ví điện tử nội địa, mạng chập chờn.