Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng một tình huống rất quen thuộc: đội QA của bạn đã test đến kiệt sức, mọi test case đều pass, không còn bug nghiêm trọng nào trong bug tracker. Bạn tự tin đưa sản phẩm lên production. Rồi ba ngày sau, giám đốc kinh doanh gọi điện: "Cái nút duyệt hợp đồng này đúng là bấm được, nhưng nó không đúng với quy trình phê duyệt của công ty tôi. Nhân viên không thể dùng được." Sản phẩm chạy đúng về mặt kỹ thuật, nhưng sai về mặt nghiệp vụ. Đây chính là khoảng trống mà Acceptance Testing — đặc biệt là UAT (User Acceptance Testing) — sinh ra để lấp đầy.
Trong toàn bộ khóa học này, chúng ta đã và sẽ nói nhiều về cách QA tự tay thiết kế test case, tìm bug, kiểm thử hộp đen hộp trắng. Nhưng bài 15 này khác hẳn về bản chất: nó là bước kiểm thử mà người thực hiện chính KHÔNG phải là QA, mà là người dùng cuối hoặc đại diện nghiệp vụ (business user). QA lúc này chuyển vai từ "người test" sang "người tổ chức và điều phối". Đây là điểm chuyển giao quan trọng nhất trong vòng đời một dự án — nơi câu hỏi thay đổi từ "Phần mềm có chạy đúng không?" sang "Phần mềm có giải quyết đúng bài toán của khách hàng không?".
Gắn liền với UAT là khái niệm DoD (Definition of Done) — định nghĩa thế nào là "xong". Nếu không có DoD rõ ràng, mỗi người trong đội sẽ hiểu chữ "xong" theo một kiểu, và UAT sẽ trở thành một cuộc tranh cãi bất tận. Hiểu và làm chủ hai khái niệm này giúp bạn — với tư cách tester — trở thành cầu nối giữa đội kỹ thuật và khách hàng, một kỹ năng khiến bạn khác biệt hoàn toàn so với một người chỉ biết click chuột tìm lỗi.
Khái niệm cốt lõi
Acceptance Testing là gì
Acceptance Testing (kiểm thử chấp nhận) là cấp độ kiểm thử cuối cùng, được thực hiện để xác định xem hệ thống có thỏa mãn các tiêu chí nghiệp vụ và có sẵn sàng để bàn giao / release hay chưa. Điểm mấu chốt: trọng tâm không phải là "tìm bug kỹ thuật" mà là xác nhận (validation) rằng sản phẩm đáp ứng đúng nhu cầu thực tế.
Người ta hay phân biệt hai động từ tiếng Anh: verification và validation. Các cấp test trước đó (unit, integration, system) chủ yếu làm verification — "chúng ta có xây dựng sản phẩm ĐÚNG CÁCH không?". Còn Acceptance Testing làm validation — "chúng ta có xây dựng ĐÚNG SẢN PHẨM mà khách hàng cần không?". Một phần mềm có thể pass mọi verification nhưng vẫn thất bại validation, vì nó giải quyết sai bài toán.
Các loại Acceptance Testing
Đây không chỉ có UAT. Trong thực tế bạn sẽ gặp nhiều biến thể, và một tester chuyên nghiệp cần phân biệt được:
- UAT (User Acceptance Testing): người dùng cuối hoặc đại diện nghiệp vụ kiểm tra xem hệ thống có phục vụ đúng công việc hàng ngày của họ không. Đây là loại phổ biến và quan trọng nhất.
- BAT (Business Acceptance Testing): tập trung vào việc hệ thống có mang lại giá trị nghiệp vụ, có phù hợp với mục tiêu kinh doanh và quy trình công ty không.
- OAT (Operational Acceptance Testing): kiểm tra khía cạnh vận hành — backup, khôi phục dữ liệu, quy trình cài đặt, bảo trì, giám sát. Do đội vận hành / DevOps thực hiện.
- Contract Acceptance Testing: hệ thống được nghiệm thu dựa trên các tiêu chí đã cam kết trong hợp đồng. Rất phổ biến ở các dự án outsource tại Việt Nam.
- Regulation / Compliance Acceptance Testing: kiểm tra tuân thủ quy định pháp luật, ví dụ nghị định về bảo vệ dữ liệu cá nhân, quy định của Ngân hàng Nhà nước với sản phẩm fintech.
- Alpha & Beta Testing: alpha do người trong nội bộ (không thuộc đội dev) thực hiện tại môi trường của nhà phát triển; beta do người dùng thật thực hiện tại môi trường của họ. (Beta Testing được đào sâu ở bài khác trong khóa; ở đây chỉ nêu để bạn thấy bức tranh tổng thể.)
Vai trò của QA trong UAT
Đây là điều nhiều bạn hiểu sai. Trong UAT, QA không phải người bấm nút test chính. Nhưng vai trò của QA lại cực kỳ nặng, gồm:
- Chuẩn bị UAT test scenario viết bằng ngôn ngữ nghiệp vụ (không phải ngôn ngữ kỹ thuật) để business user dễ đọc.
- Chuẩn bị test data giống thực tế (ví dụ danh sách khách hàng, đơn hàng mẫu).
- Chuẩn bị môi trường UAT ổn định, tách biệt với môi trường dev/staging đang thay đổi liên tục.
- Đào tạo người dùng cách thực hiện, cách ghi nhận lỗi.
- Điều phối buổi UAT, thu thập phản hồi, phân loại đâu là bug thật, đâu là hiểu nhầm, đâu là yêu cầu mới (change request).
- Tổng hợp và báo cáo kết quả để ra quyết định go/no-go.
Definition of Done (DoD)
DoD là một danh sách các tiêu chí mà một hạng mục công việc (user story, feature, release) phải thỏa mãn thì mới được coi là "hoàn thành". DoD được cả đội thống nhất trước và áp dụng chung cho mọi hạng mục — nó là tấm gương chung để mọi người soi vào.
Cần phân biệt DoD với Acceptance Criteria (AC):
- Acceptance Criteria là riêng cho từng user story — mô tả cụ thể story đó phải làm được gì (ví dụ: "Người dùng nhập sai mật khẩu 5 lần thì tài khoản bị khóa 15 phút"). AC trả lời "story này xong khi nào".
- DoD là chung cho mọi story — mô tả chất lượng tối thiểu áp dụng cho tất cả (ví dụ: "code đã được review", "test tự động pass", "đã cập nhật tài liệu", "không còn bug severity cao"). DoD trả lời "bất kỳ việc gì cũng phải đạt các điều này mới gọi là xong".
Tình huống thực tế
Tình huống 1: Ngân hàng số triển khai module duyệt vay
Một ngân hàng thương mại tại TP.HCM thuê đội outsource xây dựng module phê duyệt khoản vay tín chấp. Đội dev bàn giao với niềm tự hào: 320 test case pass, 0 bug nghiêm trọng. Nhưng khi bước vào UAT, các chuyên viên tín dụng thực tế ngồi test lại phát hiện: hệ thống cho phép chuyên viên tự phê duyệt khoản vay do chính mình tạo — điều vi phạm nguyên tắc maker-checker (người tạo và người duyệt phải khác nhau) bắt buộc trong ngành ngân hàng.
Về mặt kỹ thuật, không có bug nào cả — hệ thống hoạt động đúng như đặc tả. Nhưng đặc tả ban đầu đã thiếu ràng buộc nghiệp vụ này, và chỉ đến khi người dùng thật (business user) thao tác thì mới lộ ra.
Bài học: UAT phát hiện được lớp lỗi mà mọi cấp test kỹ thuật không thể chạm tới — lỗi về quy trình nghiệp vụ và tuân thủ. Đây là lý do người thực hiện UAT bắt buộc phải là người hiểu nghiệp vụ, không phải QA. Sau vụ này, đội bổ sung vào DoD cấp release dòng: "Mọi luồng phê duyệt tài chính phải được nghiệp vụ xác nhận tuân thủ maker-checker".
Tình huống 2: Sàn TMĐT và cái bẫy "UAT không có DoD"
Một startup thương mại điện tử giả định tên ChợViệt chuẩn bị ra tính năng "gộp đơn nhiều shop, một lần thanh toán". Họ tổ chức UAT với 8 người từ đội vận hành và chăm sóc khách hàng. Buổi UAT kéo dài 3 ngày, mọi người gửi về hơn 60 phản hồi qua nhóm Zalo: "chỗ này chữ hơi nhỏ", "màu nút không đẹp", "sao không có tính năng lưu giỏ hàng luôn?", "lúc mạng yếu bị lỗi"...
Vấn đề là ChợViệt không định nghĩa trước tiêu chí vào (entry criteria) và tiêu chí ra (exit criteria) của UAT, cũng không có DoD. Kết quả: không ai biết khi nào UAT được coi là "đạt". Phản hồi trộn lẫn giữa bug thật, ý kiến thẩm mỹ cá nhân, và yêu cầu tính năng mới. Ngày release bị lùi hai tuần chỉ để tranh cãi "cái này có phải bug không hay là feature mới".
Bài học: UAT mà không có DoD và exit criteria rõ ràng sẽ biến thành một cái hố không đáy. Ở lần sau, QA của ChợViệt đưa ra quy tắc: mỗi phản hồi phải được gán nhãn Bug / Change Request / Won't Fix, và UAT chỉ được coi là PASS khi "100% test scenario nghiệp vụ chạy đúng và không còn defect priority Cao/Trung bình" — một exit criteria đo lường được.
Tình huống 3: Dự án outsource và Contract Acceptance
Một công ty phần mềm ở Đà Nẵng làm hệ thống quản lý kho cho khách hàng Nhật Bản theo hợp đồng cố định. Hợp đồng ghi rõ 40 chức năng cần bàn giao kèm tiêu chí nghiệm thu cho từng chức năng. Khi nghiệm thu (Contract Acceptance Testing), phía khách hàng đối chiếu từng dòng. Có 3 chức năng khách cho là "chưa đạt" vì tốc độ xử lý báo cáo tồn kho quá 5 giây, trong khi hợp đồng ghi "phản hồi dưới 3 giây".
Vì tiêu chí này đã nằm trong hợp đồng và trong DoD của dự án, phía Đà Nẵng không thể chối, phải tối ưu lại trước khi được thanh toán đợt cuối.
Bài học: Với dự án outsource, Acceptance Criteria trong hợp đồng chính là DoD có tính pháp lý. Một tester giỏi phải đọc kỹ hợp đồng và biến mọi cam kết (kể cả về hiệu năng) thành test scenario có thể đo được ngay từ đầu, tránh việc "đến lúc nghiệm thu mới ngã ngửa".
Hướng dẫn từng bước
Đây là quy trình tổ chức một chu kỳ UAT bài bản mà bạn có thể áp dụng ngay:
Bước 1 — Lập kế hoạch UAT. Xác định phạm vi (feature/luồng nào sẽ được nghiệm thu), ai là người tham gia (chọn business user thật sự đại diện cho người dùng cuối), thời gian, và quan trọng nhất là entry criteria (điều kiện để bắt đầu, ví dụ: system test đã pass, không còn bug severity cao) và exit criteria (điều kiện để kết thúc và ký nghiệm thu).
Bước 2 — Viết UAT scenario theo ngôn ngữ nghiệp vụ. Đừng viết "Verify API POST /orders trả về 201". Hãy viết "Nhân viên bán hàng tạo một đơn hàng cho khách A gồm 3 sản phẩm, áp mã giảm giá, và xác nhận đơn thành công". Mỗi scenario nên gắn với một Acceptance Criteria hoặc một mục tiêu nghiệp vụ cụ thể.
Bước 3 — Chuẩn bị môi trường và dữ liệu UAT. Dựng môi trường riêng, dữ liệu càng giống thực tế càng tốt (ẩn danh dữ liệu thật nếu cần để bảo mật). Môi trường này phải ổn định, không bị dev đẩy code mới liên tục trong lúc UAT diễn ra.
Bước 4 — Đào tạo người tham gia. Hướng dẫn business user cách thao tác, cách ghi lại vấn đề (chụp màn hình, mô tả bước tái hiện), và kênh báo cáo tập trung (một bảng tính hoặc công cụ như Jira, không phải chat rời rạc).
Bước 5 — Thực thi UAT. Người dùng chạy các scenario. QA đứng cạnh hỗ trợ, ghi nhận, và phân loại ngay mỗi phản hồi thành: Bug (sai so với AC), Change Request (yêu cầu mới), hoặc Hiểu nhầm (cần đào tạo thêm).
Bước 6 — Phân loại và xử lý defect. Bug được đưa vào quy trình fix. Change Request được đẩy sang Product Owner quyết định làm ở release nào. So chiếu tất cả với DoD.
Bước 7 — Đánh giá exit criteria và Sign-off. Khi đạt exit criteria, người có thẩm quyền (thường là Product Owner hoặc đại diện khách hàng) ký UAT sign-off — văn bản xác nhận chấp nhận sản phẩm. Đây là căn cứ để ra quyết định go/no-go cho release. Sign-off nên là văn bản, không phải một câu "ok em" qua chat.
Lỗi thường gặp & mẹo
Lỗi 1 — Biến UAT thành vòng test kỹ thuật lần hai. Nhiều đội bắt business user đi tìm bug kỹ thuật vụn vặt. Sai. UAT là để xác nhận giá trị nghiệp vụ. Bug kỹ thuật phải được QA dọn sạch trước khi vào UAT (đó là ý nghĩa của entry criteria).
Lỗi 2 — Không có Definition of Done, hoặc DoD chỉ nằm trong đầu. DoD phải được viết ra, dán nơi ai cũng thấy, và cả đội cùng thống nhất. DoD mơ hồ kiểu "code chạy được" là vô dụng.
Lỗi 3 — Chọn sai người làm UAT. Chọn người rảnh thay vì người hiểu nghiệp vụ. Kết quả là UAT pass nhưng người dùng thật vẫn không dùng được.
Lỗi 4 — Lẫn lộn Acceptance Criteria và DoD. Nhớ: AC riêng cho từng story, DoD chung cho mọi story. Trộn hai thứ này khiến việc lập kế hoạch rối loạn.
Lỗi 5 — Không phân biệt Bug và Change Request trong UAT. Mọi ý kiến "giá mà có thêm..." đều bị coi là bug, làm scope phình to và deadline vỡ. Hãy gán nhãn ngay từ lúc nhận phản hồi.
Mẹo hay:
- Chuẩn bị sẵn template ghi nhận defect UAT đơn giản cho người không chuyên: Ai gặp / Ở màn hình nào / Làm gì / Mong đợi gì / Thực tế ra sao / Ảnh chụp.
- Đặt exit criteria đo lường được: "0 defect priority Cao, ≤3 defect Trung bình có workaround" tốt hơn "chất lượng ổn".
- Tổ chức một buổi UAT dry-run nội bộ trước để phát hiện kịch bản viết sai hoặc dữ liệu thiếu, tránh lãng phí thời gian của business user.
- Luôn lấy sign-off bằng văn bản — nó bảo vệ bạn khi có tranh cãi sau release.
Bài tập thực hành
- Viết DoD. Cho một dự án app đặt đồ ăn, hãy viết một Definition of Done ở cấp user story gồm ít nhất 6 tiêu chí, và một DoD cấp release gồm ít nhất 4 tiêu chí bổ sung. Phân biệt rõ đâu là DoD, đâu sẽ là Acceptance Criteria.
- Phân loại phản hồi. Cho các phản hồi UAT sau, hãy gán nhãn Bug / Change Request / Hiểu nhầm: (a) "Bấm thanh toán MoMo báo lỗi 500"; (b) "Nút màu xanh nên đổi thành cam cho nổi bật"; (c) "Tôi không tìm thấy chỗ đổi mật khẩu" (thực ra có, ở menu Cài đặt); (d) "Cần thêm tính năng đặt lịch giao hàng".
- Thiết kế exit criteria. Viết entry criteria và exit criteria cho một chu kỳ UAT của tính năng "đăng nhập bằng số điện thoại + OTP". Đảm bảo exit criteria có thể đo lường được.
- Viết UAT scenario. Chuyển yêu cầu kỹ thuật sau thành một UAT scenario bằng ngôn ngữ nghiệp vụ: "Hệ thống gọi API tính phí ship dựa trên khoảng cách và trả về giá trước khi user xác nhận đơn".
Tóm tắt
- Acceptance Testing là cấp kiểm thử cuối, làm validation — xác nhận sản phẩm giải quyết đúng bài toán của khách hàng, khác với các cấp trước làm verification.
- UAT do business user / người dùng cuối thực hiện, không phải QA. Vai trò của QA là chuẩn bị, đào tạo, điều phối và tổng hợp — một vai trò cầu nối quan trọng.
- Có nhiều loại: UAT, BAT, OAT, Contract Acceptance, Compliance — mỗi loại phục vụ một mục tiêu nghiệm thu khác nhau. Với dự án outsource Việt Nam, Contract Acceptance đặc biệt quan trọng vì gắn với thanh toán.
- DoD (Definition of Done) là bộ tiêu chí chung để một hạng mục được coi là "xong"; Acceptance Criteria là tiêu chí riêng cho từng story. Đừng nhầm hai khái niệm này.
- Một chu kỳ UAT tốt cần entry criteria, exit criteria đo lường được, và sign-off bằng văn bản. Thiếu chúng, UAT biến thành cái hố không đáy như tình huống ChợViệt.
- Ba tình huống cho thấy: UAT phát hiện lỗi nghiệp vụ mà test kỹ thuật bỏ sót (ngân hàng), thất bại khi thiếu DoD (TMĐT), và mang tính pháp lý trong hợp đồng (outsource Đà Nẵng).