Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn vừa dẫn dắt một dự án testing suốt ba tháng. Đội của bạn viết hàng nghìn test case, mọi chức năng đều "pass": đăng nhập chạy đúng, thêm sản phẩm vào giỏ hàng đúng, thanh toán ra hóa đơn đúng. Bạn tự tin ký duyệt release. Rồi ngày khuyến mãi 12/12 đến, 50.000 người dùng đổ vào cùng lúc — website sập trong 4 phút, giỏ hàng mất dữ liệu, và một lỗ hổng bảo mật để lộ số điện thoại khách hàng lên trang chi tiết đơn. Mọi chức năng đều "đúng", nhưng sản phẩm vẫn thất bại thảm hại.
Đó chính là khoảng trống mà Non-Functional Testing (NFT — kiểm thử phi chức năng) lấp vào. Nếu Functional Testing trả lời câu hỏi "phần mềm có LÀM đúng việc không?", thì Non-Functional Testing trả lời câu hỏi khó hơn nhiều: "phần mềm làm việc đó TỐT đến mức nào?" — nhanh không, chịu tải được không, an toàn không, dễ dùng không, phục hồi được sau sự cố không.
Với vai trò QA Lead hoặc người xây dựng test strategy, bài này cực kỳ quan trọng vì đa số sự cố nghiêm trọng ngoài production (sập hệ thống, rò rỉ dữ liệu, trải nghiệm tệ) không đến từ lỗi chức năng, mà đến từ những thuộc tính phi chức năng bị bỏ quên. Đây là bài "tổng quan bản đồ" — giúp bạn nhìn thấy toàn cảnh các loại NFT trước khi đào sâu vào Performance (Bài 24), Security (Bài 25), Accessibility (Bài 26) ở các bài sau.
Khái niệm cốt lõi
"Functional" và "Non-functional" — ranh giới thực sự
Cách phân biệt đơn giản nhất mà tôi hay dùng khi mentor:
- Functional testing kiểm tra CÁI GÌ hệ thống làm — hành vi cụ thể theo yêu cầu nghiệp vụ. Ví dụ: "Người dùng nhập đúng mật khẩu thì đăng nhập thành công", "Chuyển khoản 1 triệu thì số dư giảm đúng 1 triệu".
- Non-functional testing kiểm tra NHƯ THẾ NÀO hệ thống làm việc đó — các thuộc tính chất lượng (quality attributes). Ví dụ: "Đăng nhập phải phản hồi dưới 2 giây", "Hệ thống chịu được 10.000 người chuyển khoản đồng thời", "Mật khẩu phải được mã hóa, không lưu dạng plaintext".
Các nhóm NFT chính (theo ISO/IEC 25010)
Chuẩn quốc tế ISO/IEC 25010 định nghĩa mô hình chất lượng sản phẩm phần mềm, và phần lớn NFT xoay quanh các đặc tính này. Tôi tóm gọn thành những nhóm bạn cần nắm:
1. Performance Efficiency (Hiệu năng) — Tốc độ và mức tiêu thụ tài nguyên.
- Load testing: kiểm tra hệ thống dưới tải dự kiến (ví dụ 5.000 user).
- Stress testing: đẩy tải vượt giới hạn để tìm điểm gãy.
- Spike testing: tải tăng đột ngột (như flash sale).
- Soak/Endurance testing: chạy tải trung bình trong thời gian dài (24–72h) để phát hiện memory leak.
- Scalability testing: khả năng mở rộng khi tăng tài nguyên.
3. Usability (Khả dụng) — Sản phẩm dễ học, dễ dùng, ít gây lỗi cho người dùng. Thường đo qua usability testing với người dùng thật.
4. Reliability (Độ tin cậy) — Khả năng hoạt động ổn định: MTBF (thời gian trung bình giữa các lần lỗi), khả năng phục hồi (recovery testing), khả năng chịu lỗi (fault tolerance), failover.
5. Compatibility (Tương thích) — Chạy đúng trên nhiều trình duyệt, thiết bị, hệ điều hành, độ phân giải (cross-browser, cross-device testing).
6. Maintainability (Khả năng bảo trì) và Portability (Khả năng chuyển đổi) — thường thiên về đánh giá kiến trúc/code hơn là kiểm thử động, nhưng vẫn thuộc phạm vi chất lượng phi chức năng.
Ngoài ra còn có các loại chuyên biệt như Accessibility testing (khả năng tiếp cận cho người khuyết tật — WCAG), Localization/Internationalization testing (đa ngôn ngữ, định dạng tiền tệ/ngày tháng — rất quan trọng khi làm sản phẩm đa quốc gia ở Đông Nam Á).
Đặc điểm khiến NFT khó hơn Functional Testing
Điều tôi luôn nhấn mạnh với học viên: NFT khó ở ba điểm.
Thứ nhất, NFT cần có tiêu chí đo lường rõ ràng (metrics). "Website phải nhanh" là vô nghĩa. Phải là "trang chủ tải xong dưới 2,5 giây với 90% người dùng (p90) tại băng thông 4G". Không có con số thì không thể kiểm thử.
Thứ hai, NFT phụ thuộc mạnh vào môi trường. Bạn không thể đo hiệu năng chính xác trên máy dev. Cần môi trường staging giống production về cấu hình, dữ liệu, hạ tầng.
Thứ ba, NFT thường bị hoãn đến cuối dự án — và đó là sai lầm chết người, vì khi phát hiện vấn đề kiến trúc thì đã quá muộn để sửa rẻ.
Tình huống thực tế
Ví dụ 1 — Sàn TMĐT Việt và ngày Flash Sale (Performance & Spike)
Một sàn thương mại điện tử tại TP.HCM (gọi là ShopViet cho tiện) chuẩn bị chương trình "Sale 9.9". Đội QA đã test toàn bộ chức năng: đặt hàng, áp mã giảm giá, thanh toán VNPay — tất cả pass 100%. Nhưng họ chưa từng làm spike testing.
Đúng 0h ngày 9/9, lượng truy cập nhảy từ 3.000 lên 45.000 người dùng đồng thời trong vòng 2 phút. Database connection pool cạn kiệt, thời gian phản hồi API giỏ hàng tăng từ 200ms lên 18 giây, và hàng loạt đơn hàng bị trừ kho hai lần do race condition khi hệ thống quá tải. Ước tính thiệt hại: hơn 2 tỷ đồng doanh thu bị mất trong 40 phút, chưa kể khủng hoảng truyền thông.
Bài học rút ra: Chức năng đúng không đảm bảo sản phẩm sống sót dưới tải thật. Nếu đội đã chạy spike test mô phỏng kịch bản 0h flash sale, họ sẽ phát hiện giới hạn connection pool và race condition trước khi lên production. NFT phải là một phần bắt buộc trong Definition of Done cho các tính năng có lưu lượng cao.
Ví dụ 2 — Ứng dụng ngân hàng số và lỗ hổng phân quyền (Security)
Một fintech ở Singapore triển khai app cho vay tiêu dùng tại thị trường Đông Nam Á. Đội QA test kỹ luồng chức năng: đăng ký khoản vay, duyệt hồ sơ, giải ngân — hoàn hảo. Nhưng họ chưa làm security testing đầy đủ.
Trong đợt pentest độc lập do đối tác bảo hiểm yêu cầu, chuyên gia bảo mật phát hiện lỗ hổng IDOR (Insecure Direct Object Reference): chỉ cần đổi số ID trong URL /loan/detail?id=10023 thành id=10024, người dùng A có thể xem toàn bộ hồ sơ vay, CCCD và thu nhập của người dùng B. Đây thuần túy là lỗi phi chức năng — chức năng "xem chi tiết khoản vay" vẫn chạy đúng, nhưng thuộc tính bảo mật (phân quyền theo chủ sở hữu) bị bỏ sót.
May mắn lỗ hổng được bắt trước khi ra mắt. Nếu lộ ra ngoài, ngoài thiệt hại pháp lý theo quy định bảo vệ dữ liệu, công ty còn có nguy cơ mất giấy phép hoạt động.
Bài học rút ra: Với sản phẩm tài chính, security testing không phải "nice to have" mà là điều kiện tiên quyết để tồn tại. QA Lead cần đưa checklist bảo mật (phân quyền, mã hóa, xác thực) vào ngay từ giai đoạn thiết kế test strategy, không đợi đến pentest cuối cùng.
Ví dụ 3 — App học tiếng Anh và bài toán tương thích (Compatibility & Usability)
Một startup edtech Việt Nam ra mắt app học tiếng Anh cho học sinh cấp 2. Trên iPhone đời mới của đội dev, app chạy mượt. Nhưng học sinh mục tiêu phần lớn dùng điện thoại Android tầm trung, màn hình nhỏ, RAM thấp.
Sau khi ra mắt, tỷ lệ gỡ app trong 7 ngày lên tới 60%. Điều tra ra hai vấn đề phi chức năng: (1) compatibility — trên các máy Android màn 5 inch, nút "Nộp bài" bị đẩy ra ngoài màn hình, học sinh không tìm thấy; (2) performance — trên máy RAM 3GB, mỗi lần chuyển bài mất 6–8 giây, khiến trẻ mất kiên nhẫn.
Sau khi bổ sung cross-device testing trên ma trận 15 dòng máy Android phổ biến ở Việt Nam và tối ưu thời gian tải xuống dưới 2 giây, tỷ lệ giữ chân 7 ngày cải thiện từ 40% lên 71%.
Bài học rút ra: Compatibility và usability là NFT nhưng ảnh hưởng trực tiếp đến số liệu kinh doanh. Test trên thiết bị của dev không đại diện cho thiết bị của người dùng thật — hãy xây ma trận thiết bị dựa trên dữ liệu thực của thị trường.
Hướng dẫn từng bước
Đây là quy trình tôi khuyên các QA Lead áp dụng để đưa NFT vào chiến lược kiểm thử một cách bài bản.
Bước 1 — Thu thập Non-Functional Requirements (NFR). Ngồi với Product Owner, kiến trúc sư và stakeholder để làm rõ các yêu cầu phi chức năng. Đừng chấp nhận mô tả mơ hồ. Biến "hệ thống phải nhanh" thành "p95 response time < 1s dưới tải 5.000 concurrent user". Không có NFR đo được thì không có NFT.
Bước 2 — Ưu tiên theo rủi ro. Bạn không thể test tất cả mọi thuộc tính với mọi tính năng. Hãy lập ma trận: tính năng nào × thuộc tính nào có rủi ro cao nhất? Với sàn TMĐT, performance của luồng thanh toán là ưu tiên số 1. Với app y tế, security và reliability đứng đầu.
Bước 3 — Chọn loại NFT phù hợp cho từng rủi ro. Rủi ro tải cao → load/stress/spike test. Rủi ro dữ liệu nhạy cảm → security test. Rủi ro nhiều thiết bị → compatibility test. Ánh xạ rõ ràng rủi ro → loại test → công cụ.
Bước 4 — Chuẩn bị môi trường và dữ liệu giống production. Đây là bước hay bị xem nhẹ. Môi trường test hiệu năng phải tương đương production về cấu hình server, cấu trúc dữ liệu và khối lượng dữ liệu (không thể đo hiệu năng query trên bảng 1.000 dòng rồi kết luận cho bảng 10 triệu dòng).
Bước 5 — Chọn công cụ. Một số công cụ phổ biến để bạn định hướng: JMeter, k6, Gatling, Locust cho performance; OWASP ZAP, Burp Suite cho security; BrowserStack, LambdaTest cho compatibility; axe, Lighthouse cho accessibility. (Chi tiết từng loại sẽ có ở các bài chuyên sâu tiếp theo.)
Bước 6 — Thiết lập baseline và ngưỡng pass/fail rõ ràng. Ví dụ: "Nếu error rate > 1% hoặc p95 > 2s thì fail build". Ngưỡng phải được thống nhất trước, không tranh cãi sau khi có kết quả.
Bước 7 — Tích hợp sớm và liên tục (shift-left). Đưa các bài test phi chức năng nhẹ (smoke performance, quét bảo mật cơ bản) vào pipeline CI/CD để phát hiện suy giảm sớm, thay vì để dồn đến cuối dự án.
Bước 8 — Báo cáo dưới ngôn ngữ rủi ro kinh doanh. Đừng chỉ báo "p95 là 3,2s". Hãy nói "với hiệu năng hiện tại, trong đợt sale dự kiến 40.000 user, hệ thống có nguy cơ sập, tương ứng rủi ro mất X tỷ doanh thu". Stakeholder ra quyết định dựa trên rủi ro, không dựa trên con số kỹ thuật.
Lỗi thường gặp & mẹo
Lỗi 1: Coi NFT là việc làm sau cùng. Nhiều đội hoãn NFT đến sát ngày release. Khi phát hiện vấn đề hiệu năng do lỗi kiến trúc, chi phí sửa gấp hàng chục lần so với phát hiện sớm. Mẹo: đưa NFR vào ngay từ giai đoạn thiết kế, làm smoke NFT trong mỗi sprint.
Lỗi 2: Yêu cầu phi chức năng mơ hồ. "App phải mượt", "phải bảo mật" là không kiểm thử được. Mẹo: mọi NFR phải có con số, có điều kiện, có ngưỡng chấp nhận. Áp dụng tư duy SMART cho NFR.
Lỗi 3: Test hiệu năng trên môi trường sai. Chạy load test trên staging cấu hình yếu hơn production rồi kết luận sai lệch. Mẹo: ghi rõ sự khác biệt môi trường trong báo cáo, và ưu tiên môi trường tương đương production cho các test quyết định release.
Lỗi 4: Nhầm lẫn giữa các loại performance test. Load, stress, spike, soak khác nhau về mục đích. Chạy load test rồi tưởng mình đã kiểm tra khả năng chịu spike. Mẹo: viết rõ mục tiêu từng bài test — bạn đang tìm điểm gãy, đo tải bình thường, hay tìm memory leak?
Lỗi 5: Bỏ quên các NFT "vô hình" như accessibility và localization. Đặc biệt nguy hiểm khi làm sản phẩm cho thị trường đa dạng hoặc chịu quy định pháp lý về khả năng tiếp cận. Mẹo: đưa accessibility và localization vào checklist NFT ngay từ đầu nếu sản phẩm phục vụ công chúng rộng.
Mẹo tổng quát: Hãy giữ một "NFT checklist" cho tổ chức, ánh xạ từng loại sản phẩm với các thuộc tính phi chức năng bắt buộc. Sản phẩm ngân hàng, TMĐT, y tế, edtech sẽ có bộ ưu tiên NFT khác nhau — chuẩn hóa việc này giúp đội mới không bỏ sót.
Bài tập thực hành
Bài 1 — Phân loại. Cho danh sách yêu cầu sau, phân loại functional hay non-functional, và nếu là non-functional thì thuộc nhóm nào (performance/security/usability/reliability/compatibility):
- "Người dùng đặt lại mật khẩu qua email."
- "Trang danh sách sản phẩm tải dưới 2 giây trên 4G."
- "Mật khẩu lưu dưới dạng đã băm (hashed), không plaintext."
- "Hệ thống hoạt động đúng trên Chrome, Safari, và Firefox phiên bản mới nhất."
- "Sau khi server chính lỗi, hệ thống tự chuyển sang server dự phòng trong 30 giây."
Bài 3 — Ma trận rủi ro. Chọn một sản phẩm bạn quen thuộc (ví dụ ví điện tử MoMo, sàn Tiki, app giao đồ ăn). Lập bảng gồm 5 tính năng quan trọng nhất × các thuộc tính NFT, và đánh dấu mức rủi ro (Cao/Trung bình/Thấp) cho từng ô. Từ đó chỉ ra 3 loại NFT bạn sẽ ưu tiên đầu tư trước.
Bài 4 — Tình huống ra quyết định. Bạn là QA Lead, còn 5 ngày trước release. Kết quả load test cho thấy p95 response time là 3,5 giây (ngưỡng chấp nhận là 2 giây) ở mức tải dự kiến. Viết một đoạn báo cáo ngắn (5–7 câu) trình bày cho ban lãnh đạo bằng ngôn ngữ rủi ro kinh doanh, và đề xuất quyết định.
Tóm tắt
Non-Functional Testing kiểm tra chất lượng của phần mềm — nó làm việc TỐT đến mức nào — chứ không phải nó làm ĐÚNG cái gì. Trong khi Functional Testing xác nhận hành vi đúng theo yêu cầu, NFT bảo vệ sản phẩm khỏi những thất bại nghiêm trọng nhất ngoài đời thực: sập dưới tải, rò rỉ dữ liệu, trải nghiệm tệ, không phục hồi được sau sự cố.
Những điểm cốt lõi cần nhớ:
- Các nhóm NFT chính xoay quanh mô hình ISO/IEC 25010: performance, security, usability, reliability, compatibility, cùng các loại chuyên biệt như accessibility và localization.
- NFT khó vì cần metrics đo được, môi trường giống production, và dễ bị hoãn đến cuối dự án.
- Quy trình bài bản: thu thập NFR đo được → ưu tiên theo rủi ro → chọn loại test và công cụ → chuẩn bị môi trường → đặt ngưỡng pass/fail → tích hợp sớm → báo cáo bằng ngôn ngữ rủi ro.
- Ba câu chuyện flash sale, IDOR ngân hàng, và app edtech đều cho thấy một sự thật: chức năng đúng KHÔNG đảm bảo sản phẩm thành công.