Product Management
Đăng nhập
ESC

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

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

Bài 55 — Test Strategy for Mobile Apps

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

Nếu bạn đang xây dựng chiến lược kiểm thử (test strategy) cho một ứng dụng web và nghĩ rằng chỉ cần "áp dụng y hệt" cho ứng dụng mobile, bạn sẽ gặp rắc rối rất nhanh. Mobile không phải là "web thu nhỏ". Nó là một thế giới hoàn toàn khác về mặt kỹ thuật: hàng nghìn loại thiết bị, hệ điều hành phân mảnh, mạng chập chờn, pin, quyền hệ thống, và đặc biệt là hai "người gác cổng" quyền lực — Apple App Store và Google Play — có thể chặn bản phát hành của bạn trong nhiều ngày.

Tôi đã chứng kiến không ít đội QA giỏi ở mảng web nhưng lúng túng khi chuyển sang mobile. Họ viết test case rất chỉn chu nhưng lại quên mất rằng bug chỉ xuất hiện trên Samsung Galaxy J-series đời cũ chạy Android 9, hoặc app crash khi người dùng đang đi thang máy mất sóng. Trong bối cảnh Việt Nam — nơi phần lớn người dùng dùng điện thoại Android tầm trung, mạng 4G không đồng đều giữa thành thị và nông thôn — những vấn đề này càng trở nên nghiêm trọng.

Bài học này giúp bạn thiết kế một test strategy dành riêng cho mobile: hiểu những khác biệt cốt lõi so với web, biết cách ưu tiên thiết bị, xử lý quy trình phát hành qua app store, và xây dựng một phương pháp kiểm thử mà đội của bạn có thể áp dụng ngay tuần sau.

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

Một test strategy cho mobile phải trả lời được câu hỏi: "Chúng ta kiểm thử cái gì, trên thiết bị nào, trong điều kiện nào, và ai/thứ gì có thể chặn bản release?". Có bốn khác biệt lớn so với web mà bạn bắt buộc phải xây dựng chiến lược xung quanh.

1. Device fragmentation — Phân mảnh thiết bị

Đây là nỗi ám ảnh lớn nhất. Trên web, bạn chỉ cần lo vài trình duyệt (Chrome, Safari, Firefox, Edge). Trên mobile, đặc biệt Android, có hơn 1.000 nhà sản xuất và hàng chục nghìn cấu hình thiết bị khác nhau — kích thước màn hình, độ phân giải, chip, RAM, phiên bản OS, giao diện tùy biến (Samsung One UI, Xiaomi MIUI, Oppo ColorOS...). Một app chạy mượt trên Pixel có thể vỡ layout trên Xiaomi Redmi vì MIUI can thiệp vào quyền chạy nền và thông báo.

Bạn không thể test tất cả. Chiến lược đúng là xây dựng một device matrix dựa trên dữ liệu thật: thiết bị nào người dùng của bạn đang dùng nhiều nhất. Nguyên tắc phổ biến là ưu tiên phủ 80% người dùng bằng khoảng 10-15 cấu hình thiết bị, kết hợp một vài thiết bị "cực đoan" (màn hình nhỏ nhất, OS cũ nhất còn hỗ trợ, thiết bị RAM thấp).

2. App store gatekeeper — Người gác cổng và độ trễ review

Trên web, bạn deploy là người dùng thấy ngay. Trên mobile, mỗi bản build phải qua quy trình duyệt của App Store (Apple) hoặc Google Play. Apple thường mất 24-48 giờ (đôi khi lâu hơn nếu bị reject vì vi phạm guideline), Google Play nhanh hơn nhưng vẫn có thể mất vài giờ đến vài ngày. Điều này thay đổi hoàn toàn cách bạn nghĩ về release: bạn không thể hotfix tức thì. Một bug nghiêm trọng lọt ra production có thể "kẹt" với người dùng trong 2-3 ngày trước khi bản vá được duyệt.

Hệ quả chiến lược: chất lượng phải được đảm bảo trước khi submit, không phải sau. Bạn cần tận dụng các cơ chế như staged rollout (Google Play cho phép phát hành dần 5% → 20% → 50% → 100%) và các kênh beta (TestFlight của Apple, Internal/Closed Testing của Google) để bắt lỗi trước khi tới toàn bộ người dùng.

3. Offline-first — Ưu tiên hoạt động offline

Mạng di động không ổn định như mạng cố định. Người dùng đi tàu điện, vào hầm gửi xe, ra vùng sóng yếu. Một app mobile tốt phải xử lý được trạng thái mất mạng, mạng chập chờn (flaky), chuyển đổi giữa WiFi và 4G. Chiến lược kiểm thử phải bao gồm các kịch bản: mất mạng giữa chừng giao dịch, mạng chậm (bạn nên test ở tốc độ 2G/3G giả lập), đồng bộ dữ liệu khi có mạng trở lại, và xử lý xung đột dữ liệu (data conflict).

4. Push notification — Thông báo đẩy

Push notification là một luồng đặc thù của mobile không có tương đương trực tiếp trên web (web có, nhưng vai trò khác hẳn). Nó liên quan tới nhiều lớp: quyền của người dùng, dịch vụ của Apple (APNs) và Google (FCM), trạng thái app (foreground/background/killed), deep link khi bấm vào thông báo. Đây là khu vực rất dễ có bug và thường bị bỏ sót trong test plan. Ngoài ra còn hàng loạt đặc thù mobile khác cần đưa vào chiến lược: quản lý quyền (permission) camera/vị trí/danh bạ, tiêu thụ pin và bộ nhớ, xử lý interrupt (cuộc gọi đến khi đang dùng app), xoay màn hình, và luồng nâng cấp phiên bản (app update).

Tình huống thực tế

Ví dụ 1: App ví điện tử và cơn ác mộng phân mảnh Android

Một startup fintech tại TP.HCM (gọi là "PayViet") ra mắt app ví điện tử. Đội QA test rất kỹ trên iPhone và vài máy Samsung cao cấp, mọi thứ hoàn hảo. Nhưng sau khi lên Google Play, tỷ lệ crash tăng vọt — cụ thể là 8% người dùng gặp lỗi khi quét mã QR thanh toán. Điều tra ra, hầu hết crash đến từ các máy Oppo và Vivo tầm trung chạy Android 10-11 với camera API cũ, vốn chiếm phần lớn thị phần ở phân khúc phổ thông Việt Nam nhưng lại không có trong device matrix của đội.

Diễn giải: Đội đã xây device matrix dựa trên thiết bị họ có sẵn trong văn phòng (toàn máy xịn) chứ không dựa trên dữ liệu người dùng thực. Sau sự cố, họ tích hợp một dịch vụ device farm (như BrowserStack hoặc AWS Device Farm) để thuê truy cập từ xa vào hàng trăm thiết bị thật, và thêm dòng máy Oppo/Vivo/Xiaomi tầm trung vào bộ test bắt buộc.

Bài học: Device matrix phải xuất phát từ analytics người dùng thật (Google Play Console, Firebase Analytics cho biết chính xác model và OS nào đang dùng app bạn), không phải từ giả định của đội. Ở Việt Nam, bỏ qua phân khúc Android tầm trung là bỏ qua đa số người dùng.

Ví dụ 2: App giao đồ ăn và bài học về app store review delay

Một app giao đồ ăn (giả định "FoodNow") phát hiện một bug tính sai phí ship vào tối thứ Sáu — đúng giờ cao điểm. Đội web quen với việc "sửa và deploy trong 15 phút" nên khá hoảng khi nhận ra bản vá iOS phải chờ Apple duyệt. Họ submit bản vá kèm yêu cầu expedited review (yêu cầu duyệt gấp), nhưng vẫn mất gần 18 giờ. Trong lúc đó, họ dùng một cơ chế cấu hình từ xa (remote config / feature flag qua Firebase) để tắt tạm tính năng tính phí động và fallback về mức phí cố định — không cần build mới.

Diễn giải: Bug production trên mobile không thể sửa nhanh như web. Đội nào lường trước điều này sẽ thiết kế app có "van an toàn": remote config, feature flag, kill switch cho phép bật/tắt tính năng mà không cần release mới.

Bài học: Chiến lược mobile phải bao gồm khả năng kiểm soát rủi ro sau khi release. Hãy đưa vào test plan cả việc kiểm thử các remote config và kill switch — vì chúng chính là cứu cánh khi app store review chặn bạn.

Ví dụ 3: App ngân hàng và luồng push notification bị bỏ sót

Một ngân hàng số (giả định "NeoBank") triển khai thông báo giao dịch qua push. Trong môi trường test, mọi thứ chạy tốt vì app luôn ở foreground. Nhưng người dùng thật phàn nàn rằng họ không nhận được thông báo biến động số dư khi app bị đóng hoàn toàn (killed state) — đặc biệt trên máy Xiaomi, nơi MIUI tự động "giết" tiến trình nền để tiết kiệm pin.

Diễn giải: Đội QA chỉ test push notification trong một trạng thái (app đang mở). Họ bỏ sót ma trận trạng thái: foreground, background, killed — nhân với các nhà sản xuất có chính sách quản lý pin khắc nghiệt.

Bài học: Với push notification, phải test đầy đủ tổ hợp trạng thái app × loại thiết bị × quyền thông báo bật/tắt. Và phải test trên thiết bị thật có OEM tùy biến (Xiaomi, Oppo), không chỉ trên emulator "sạch".

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

Đây là quy trình sáu bước để xây dựng test strategy cho một app mobile từ con số 0.

Bước 1 — Thu thập dữ liệu thiết bị & người dùng. Vào Firebase Analytics hoặc Google Play Console / App Store Connect để lấy dữ liệu: top model thiết bị, phiên bản OS phổ biến, độ phân giải màn hình, quốc gia. Nếu là app mới chưa có dữ liệu, dùng số liệu thị trường Việt Nam (StatCounter, số liệu Android tầm trung phổ biến).

Bước 2 — Xây device matrix. Lập bảng gồm cột: model, OS version, độ phân giải, % người dùng, mức ưu tiên (P0/P1/P2). Chọn ~10-15 cấu hình phủ 80% người dùng, thêm thiết bị cực đoan (OS thấp nhất còn hỗ trợ, RAM thấp nhất, màn hình nhỏ/lớn nhất). Ghi rõ thiết bị nào test thật, thiết bị nào test qua device farm.

Bước 3 — Xác định phạm vi kiểm thử đặc thù mobile. Ngoài chức năng nghiệp vụ, liệt kê các nhóm test riêng của mobile: mạng (offline, 2G/3G, chuyển WiFi↔4G), quyền (permission), interrupt (cuộc gọi/báo thức), push notification (3 trạng thái app), luồng update app, hiệu năng (pin, bộ nhớ, thời gian khởi động), và xoay/đa kích thước màn hình.

Bước 4 — Thiết kế chiến lược release. Định nghĩa các kênh: internal testing → closed beta (TestFlight/Closed Testing) → staged rollout production (5% → 20% → 50% → 100%). Đặt tiêu chí "gate" cho từng bậc (ví dụ: crash-free rate phải > 99.5% mới lên bậc tiếp theo). Trang bị remote config / kill switch để ứng phó khi không thể hotfix.

Bước 5 — Tự động hóa hợp lý. Chọn framework (Appium cho cross-platform, Espresso cho Android, XCUITest cho iOS). Ưu tiên tự động hóa smoke test và regression các luồng cốt lõi, chạy trên device farm trong CI/CD. Đừng cố tự động hóa những thứ đặc thù thiết bị khó ổn định — để đó cho manual/exploratory.

Bước 6 — Giám sát sau release. Cài công cụ crash reporting (Firebase Crashlytics, Sentry) và theo dõi crash-free rate, ANR (Application Not Responding) trên Android, performance metrics. Đây là "vòng lặp" đóng lại: dữ liệu production quay lại làm giàu cho device matrix và test case ở lần release sau.

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

Lỗi 1 — Chỉ test trên emulator/simulator. Emulator không tái hiện được vấn đề pin, camera, cảm biến, OEM tùy biến (MIUI, ColorOS), hay mạng thật. Mẹo: luôn có ít nhất một tầng test trên thiết bị thật cho các luồng P0, dùng device farm cho phần còn lại.

Lỗi 2 — Device matrix dựa trên "máy có sẵn". Như ví dụ PayViet, test bằng máy xịn của đội sẽ bỏ sót phân khúc phổ thông đông đảo. Mẹo: luôn dẫn dữ liệu từ analytics thật.

Lỗi 3 — Quên test luồng nâng cấp app (migration). Cài mới thì chạy tốt, nhưng người dùng cũ nâng cấp từ phiên bản trước có thể gặp lỗi migration dữ liệu local (database schema đổi). Mẹo: luôn test kịch bản "cài bản cũ → nâng lên bản mới" chứ không chỉ "cài mới".

Lỗi 4 — Bỏ qua permission edge cases. Người dùng từ chối quyền camera, rồi mở lại app — app phải xử lý mượt, không crash. Mẹo: test cả trường hợp cấp quyền, từ chối, và "từ chối vĩnh viễn".

Lỗi 5 — Không lường app store review. Submit sát deadline mà không có kênh beta hay kill switch. Mẹo: submit sớm, luôn giữ một cơ chế điều khiển từ xa để tắt tính năng lỗi mà không cần build mới.

Mẹo vàng: Đặt ngưỡng chất lượng định lượng — ví dụ crash-free users > 99.5%, ANR rate < 0.47% (ngưỡng "bad behavior" của Google Play) — làm điều kiện gate cho staged rollout. Con số cụ thể giúp quyết định release khách quan, không cảm tính.

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

  • Xây device matrix: Giả sử bạn phụ trách QA cho một app thương mại điện tử tại Việt Nam có 500.000 người dùng. Hãy phác thảo một device matrix gồm 12 cấu hình (model + OS + độ phân giải + mức ưu tiên P0/P1/P2), giải thích tại sao bạn chọn từng nhóm. Gợi ý: dựa vào thị phần Android tầm trung của Samsung/Xiaomi/Oppo tại Việt Nam.
  • Thiết kế ma trận push notification: Lập bảng test case cho tính năng push notification, phủ đủ tổ hợp: 3 trạng thái app (foreground/background/killed) × quyền thông báo (bật/tắt) × 2 nền tảng (iOS/Android) × ít nhất 1 thiết bị OEM tùy biến (Xiaomi). Mỗi ô ghi rõ kết quả kỳ vọng.
  • Kịch bản offline: Viết 5 test case cho luồng "thêm sản phẩm vào giỏ hàng khi mất mạng, sau đó có mạng trở lại". Bao gồm cả trường hợp xung đột dữ liệu (giá sản phẩm đã thay đổi khi đồng bộ).
  • Chiến lược release: Thiết kế kế hoạch staged rollout cho một bản cập nhật lớn, với tiêu chí gate cụ thể (crash-free rate, ANR) cho từng bậc %. Mô tả bạn sẽ làm gì nếu phát hiện bug nghiêm trọng khi đã rollout tới 20%.

Tóm tắt

Test strategy cho mobile khác biệt căn bản so với web ở bốn điểm: phân mảnh thiết bị (hàng nghìn cấu hình Android, đặc biệt phân khúc tầm trung đông đảo tại Việt Nam), người gác cổng app store (độ trễ review khiến bạn không thể hotfix tức thì), yêu cầu offline-first (mạng di động chập chờn), và luồng push notification phức tạp qua nhiều trạng thái app. Chiến lược đúng đắn xoay quanh: xây device matrix từ dữ liệu người dùng thật, kiểm thử trên thiết bị thật cho các luồng quan trọng, thiết kế quy trình release theo bậc (beta → staged rollout) với tiêu chí gate định lượng, trang bị remote config/kill switch làm van an toàn, và đóng vòng lặp bằng giám sát crash sau release. Nắm vững những nguyên tắc này, bạn sẽ không còn bị bất ngờ bởi bug chỉ xuất hiện trên một dòng máy hay trong một góc hầm gửi xe mất sóng.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi