Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là QA tại một startup ví điện tử ở TP.HCM. App của bạn phải chạy mượt trên iPhone 15 Pro của giới văn phòng, nhưng cũng phải hoạt động trên chiếc Samsung Galaxy A05 giá rẻ mà bác tài xế công nghệ dùng, hay chiếc Oppo A17 màn hình nhỏ mà mẹ bạn đang xài. Ở Việt Nam, thị phần điện thoại phân mảnh khủng khiếp: Samsung, Oppo, Xiaomi, Vivo, iPhone — mỗi hãng lại chục dòng máy, chục phiên bản Android/iOS khác nhau. Một bug chỉ xuất hiện trên Android 11 của Xiaomi Redmi có thể khiến hàng chục nghìn người dùng không thanh toán được.
Vấn đề: bạn không thể mua hết 200 mẫu điện thoại để trong tủ kính rồi ngồi test tay từng cái. Chi phí phần cứng, chi phí bảo trì pin, cập nhật OS, và nhân lực là bất khả thi. Đây chính là lý do mobile cloud testing ra đời — bạn thuê thiết bị thật (real device) đặt trong data center của nhà cung cấp cloud, chạy test tự động trên đó qua mạng, trả tiền theo phút sử dụng.
Bài này tập trung vào hai nền tảng cloud phổ biến nhất do chính các "ông lớn" hạ tầng vận hành: AWS Device Farm (Amazon) và Firebase Test Lab (Google). Đây là lựa chọn khác với các dịch vụ chuyên biệt như BrowserStack hay Sauce Labs (đã bàn ở bài trước về cross-browser cloud) — hai nền tảng này gắn chặt với hệ sinh thái AWS và Google Cloud, có ưu thế riêng về giá, tích hợp CI/CD, và độ sâu tính năng cho mobile. Nắm được chúng, bạn có thể scale test mobile lên hàng trăm cấu hình mà không tốn một xu cho phần cứng.
Khái niệm cốt lõi
Real device vs Emulator/Simulator
Trước tiên phải phân biệt rõ:
- Emulator (Android) / Simulator (iOS): máy ảo mô phỏng thiết bị, chạy trên CPU x86 của server. Nhanh, rẻ, nhưng KHÔNG phản ánh đúng hành vi phần cứng thật: hiệu năng CPU/GPU khác, không có SIM thật, sensor giả lập, và nhiều bug chỉ xuất hiện trên chip ARM thật.
- Real device (thiết bị thật): điện thoại vật lý cắm trong data center. Phản ánh chính xác trải nghiệm người dùng, bắt được bug về hiệu năng, tương thích driver, camera, GPS. Đắt hơn nhưng đáng tin cậy hơn cho test cuối.
AWS Device Farm
AWS Device Farm cho phép bạn chạy test trên hàng trăm thiết bị iOS và Android thật đặt trong hạ tầng AWS. Có hai chế độ sử dụng:
- Automated testing: upload app (file
.apk/.aabcho Android,.ipacho iOS) kèm bộ test (Appium, Espresso, XCUITest, Calabash...), chọn một device pool (nhóm thiết bị), chạy song song và nhận báo cáo kèm video, screenshot, log, performance metrics. - Remote access: điều khiển tay một thiết bị thật qua trình duyệt để debug thủ công.
- Project: đơn vị tổ chức, mỗi project có một ARN (Amazon Resource Name) định danh.
- Upload: mỗi app và mỗi test package đều được upload và có ARN riêng.
- Device pool: tập hợp thiết bị bạn muốn chạy, có thể lọc theo hãng, OS version, form factor.
- Run: một lần chạy test trên một device pool.
Firebase Test Lab
Firebase Test Lab là dịch vụ của Google, tích hợp sâu với Android (dĩ nhiên, vì Android là con của Google) và cả iOS. Điểm mạnh:
- Robo test: tính năng độc đáo — bạn KHÔNG cần viết test script. Firebase tự động "bò" (crawl) qua app, bấm vào các nút, điền form, chụp ảnh từng màn hình, phát hiện crash. Cực kỳ hữu ích cho smoke test nhanh.
- Instrumentation test: chạy Espresso (Android) hoặc XCUITest (iOS).
- Game Loop test: cho game, chạy qua các "demo loop".
- Tích hợp thẳng vào Firebase Console và gcloud CLI, báo cáo có video, screenshot, log, và thông tin về accessibility.
So sánh nhanh để chọn đúng công cụ
| Tiêu chí | AWS Device Farm | Firebase Test Lab |
|---|---|---|
| Hệ sinh thái | AWS (IAM, S3, CodePipeline) | Google Cloud, Firebase |
| Điểm mạnh riêng | Kho device lớn, remote access | Robo test không cần code |
| iOS | Có (real device) | Có (real + simulator) |
| Không cần viết test | Fuzz test (built-in) | Robo test (mạnh hơn) |
| Mô hình giá | Trả theo device-minute, có gói unmetered | Device-hour, có free tier |
Tình huống thực tế
Ví dụ 1 — Ví điện tử Việt xử lý phân mảnh Android
Một công ty fintech giả định tên PayViet ở Hà Nội có app ví điện tử 2 triệu người dùng. Đội QA 4 người trước đây test tay trên khoảng 15 chiếc điện thoại thật để trong tủ. Mỗi lần release mất 3 ngày regression, và họ vẫn liên tục nhận báo cáo lỗi từ người dùng dùng máy giá rẻ như Samsung Galaxy A04, Redmi 9A — những máy họ không có trong tủ.
Họ chuyển bộ test Appium sang chạy trên AWS Device Farm, tạo một device pool gồm 25 thiết bị phủ từ Android 9 đến Android 14, ưu tiên các dòng phổ biến tại Việt Nam theo dữ liệu từ Google Analytics của app. Kết quả sau 2 tháng:
- Regression từ 3 ngày xuống còn 90 phút (chạy song song 25 device).
- Phát hiện một bug nghiêm trọng: trên Android 9 của Oppo, bàn phím số khi nhập mã PIN bị che mất nút "Xác nhận" do bug layout — bug này chỉ xảy ra trên màn hình 720p tỉ lệ đặc thù, không xuất hiện trên máy đắt tiền của team dev.
- Chi phí khoảng 250 USD/tháng, rẻ hơn nhiều so với lương một QA test tay full-time.
Ví dụ 2 — Startup game mobile dùng Robo test để smoke test
GameHub SG, một studio game hyper-casual ở Singapore phát hành cho thị trường Đông Nam Á, cần smoke test nhanh mỗi build trước khi gửi tester nội bộ. Họ không có QA automation engineer chuyên trách, và viết test UI cho game rất khó.
Họ dùng Firebase Test Lab Robo test: mỗi khi CI build ra .apk, gcloud tự động đẩy lên Test Lab chạy Robo test trên 5 thiết bị trong 3 phút mỗi máy. Robo tự bấm khắp app, và nếu app crash, họ nhận được ngay video + stack trace.
Trong một sprint, Robo test bắt được crash khi app khởi động trên Android 11 với ngôn ngữ hệ thống là tiếng Thái — do một chuỗi resource bị thiếu bản dịch làm NullPointerException. Không ai trong team nghĩ tới việc test với locale tiếng Thái. Robo test bắt được vì nó chạy trên device được cấu hình đa dạng.
Bài học: khi chưa có test tự động bài bản, Robo test / fuzz test là "tấm lưới an toàn" chi phí thấp, bắt crash cơ bản mà không cần viết dòng code test nào.
Ví dụ 3 — Team iOS tối ưu chi phí bằng chọn đúng thiết bị
Một team làm app đặt đồ ăn ở TP.HCM ban đầu chạy XCUITest trên AWS Device Farm với tất cả thiết bị iOS có sẵn (hơn 20 máy) cho mỗi commit. Hóa đơn phình lên gần 600 USD/tháng vì trả theo device-minute và mỗi run tốn nhiều phút.
Họ tái cấu trúc chiến lược: mỗi commit chỉ chạy trên 3 thiết bị đại diện (iPhone SE cũ, iPhone 13, iPhone 15 Pro Max — phủ màn nhỏ, trung, lớn); còn full device pool 20 máy chỉ chạy nightly (mỗi đêm một lần) và trước mỗi release. Chi phí giảm còn khoảng 180 USD/tháng mà vẫn giữ độ phủ.
Bài học: không phải mọi test đều cần chạy trên mọi thiết bị mọi lúc. Phân tầng: PR check chạy ít device đại diện, nightly/release chạy full pool. Đây là cách cân bằng tốc độ, chi phí và độ phủ.
Hướng dẫn từng bước
Phần A — Chạy test trên AWS Device Farm (qua AWS CLI)
Giả sử bạn có app.apk và một test package Appium tests.zip.
Bước 1 — Tạo project và lấy ARN:
aws devicefarm create-project --name "PayViet-Mobile" --region us-west-2
Ghi lại "arn" trả về, ví dụ:
arn:aws:devicefarm:us-west-2:123456789012:project:abcd-1234
Bước 2 — Tạo upload cho app, rồi upload file lên URL trả về:
Tạo bản ghi upload
aws devicefarm create-upload \
--project-arn arn:aws:devicefarm:us-west-2:123456789012:project:abcd-1234 \
--name app.apk \
--type ANDROID_APPLệnh trả về một "url" (S3 presigned URL) và một upload "arn".
Dùng curl để đẩy file thật lên URL đó:
curl -T app.apk "https://prod-us-west-2-uploads.s3...presigned-url..."
Bước 3 — Upload test package (tương tự, với --type APPIUM_NODE_TEST_PACKAGE hoặc loại tương ứng).
Bước 4 — Tạo device pool (chọn thiết bị theo tiêu chí), hoặc dùng pool có sẵn:
aws devicefarm create-device-pool \
--project-arn <project-arn> \
--name "VN-Top-Devices" \
--rules '[{"attribute":"OS_VERSION","operator":"GREATER_THAN_OR_EQUALS","value":"\"9\""}]'
Bước 5 — Schedule run (bắt đầu chạy):
aws devicefarm schedule-run \
--project-arn <project-arn> \
--app-arn <app-upload-arn> \
--device-pool-arn <device-pool-arn> \
--name "regression-$(date +%Y%m%d)" \
--test '{"type":"APPIUM_NODE","testPackageArn":"<test-upload-arn>"}'
Bước 6 — Kiểm tra kết quả:
aws devicefarm get-run --arn <run-arn>
Xem trạng thái, số test pass/fail. Video, screenshot, log tải qua list-artifacts.
Lưu ý: trước khi schedule-run, hãy poll get-upload cho tới khi status là SUCCEEDED — AWS cần xử lý (parse) file upload trước.
Phần B — Chạy test trên Firebase Test Lab (qua gcloud CLI)
Bước 1 — Cài và đăng nhập gcloud, chọn project:
gcloud auth login
gcloud config set project my-firebase-project
Bước 2 — Chạy Robo test (không cần viết test):
gcloud firebase test android run \
--type robo \
--app app-debug.apk \
--device model=redfin,version=30,locale=vi,orientation=portrait \
--device model=a10,version=29,locale=vi \
--timeout 3m
Ở đây redfin là Pixel 5, version=30 là Android 11, locale=vi là tiếng Việt. Bạn khai báo nhiều --device để chạy song song trên nhiều cấu hình.
Bước 3 — Chạy Instrumentation test (Espresso):
gcloud firebase test android run \
--type instrumentation \
--app app-debug.apk \
--test app-debug-androidTest.apk \
--device model=redfin,version=30,locale=vi
Bước 4 — Xem kết quả: link tới Firebase Console hiện ngay trong output, kèm video, log, ảnh từng bước. Để liệt kê thiết bị khả dụng: gcloud firebase test android models list.
Phần C — Tích hợp vào CI/CD (khái quát)
Trong pipeline (GitHub Actions/Jenkins — chi tiết ở bài CI/CD), bước build ra artifact .apk/.ipa, rồi thêm một job gọi các lệnh CLI trên. Dùng service account (Firebase) hoặc IAM credentials (AWS) lưu trong secrets, không hardcode key.
Lỗi thường gặp & mẹo
- Quên chờ upload xử lý xong (AWS): gọi
schedule-runngay saucreate-uploadsẽ lỗi vì file chưa parse xong. Luôn pollget-uploadtới trạng tháiSUCCEEDED. - Chọn quá nhiều thiết bị cho mọi run: hóa đơn tăng vọt. Phân tầng PR-check (ít device) và nightly (full pool) như ví dụ 3.
- Nhầm real device với emulator: một số model trong Firebase là "virtual", một số là "physical". Test hiệu năng, camera, GPS PHẢI chọn physical device.
- Bỏ qua locale và cấu hình vùng: người dùng Việt đặt máy tiếng Việt, dấu tiếng Việt, định dạng số/ngày khác. Luôn thêm
locale=vivào ít nhất một device để bắt bug bản địa hóa. - Test quá dài bị timeout: mặc định Robo test và các run có giới hạn thời gian. Chia nhỏ test suite, tăng
--timeouthợp lý. - Không tận dụng free tier / gói unmetered: Firebase Test Lab có free tier hàng ngày cho team nhỏ; AWS có gói unmetered (trả cố định theo slot device thay vì theo phút) rẻ hơn khi bạn chạy rất nhiều. Tính toán khối lượng để chọn mô hình giá phù hợp.
- Region quá xa: chọn AWS region gần nhất (Singapore, Tokyo) để giảm độ trễ upload artifact từ Việt Nam.
- Bỏ quên dọn dẹp: xóa upload cũ, tránh tích tụ artifact tốn dung lượng và gây rối.
Bài tập thực hành
- Khảo sát thiết bị: mở Google Play Console (hoặc dùng số liệu thị phần công khai) của một app bạn biết, liệt kê Top 10 model + OS version phổ biến nhất tại Việt Nam. Từ đó thiết kế một device pool 8–10 máy phủ ~80% người dùng.
- Firebase Robo test: tạo một Firebase project miễn phí, build một app Android demo (hoặc lấy
.apkmẫu), chạygcloud firebase test android run --type robotrên 2 thiết bị vớilocale=vi. Xem video kết quả trên Console và ghi lại: có màn hình nào Robo không "bò" tới được không? Vì sao? - So sánh chi phí: giả sử bạn chạy 30 lần test/ngày, mỗi lần 5 device, mỗi device 4 phút. Ước tính chi phí trên AWS Device Farm (theo mô hình per-minute) so với việc mua gói unmetered. Ở khối lượng nào thì unmetered rẻ hơn?
- Phân tầng chiến lược: viết ra (bằng lời) một chiến lược 2 tầng cho một app: PR-check chạy device nào, nightly chạy device nào, release chạy gì. Giải thích lý do chọn từng thiết bị đại diện.
- Nâng cao: viết script bash tự động hóa toàn bộ luồng AWS Device Farm (create-upload → poll SUCCEEDED → schedule-run → poll run kết thúc → in kết quả). Đây là nền tảng để nhúng vào CI/CD.
Tóm tắt
Mobile cloud testing giải quyết bài toán cốt lõi của QA mobile tại Việt Nam: phân mảnh thiết bị không thể phủ bằng cách mua điện thoại thật. Hai nền tảng lớn là AWS Device Farm (kho device khổng lồ, remote access, tích hợp AWS, có fuzz test built-in) và Firebase Test Lab (Robo test không cần viết code, tích hợp Google/Firebase, có free tier, mạnh cho Android).
Ba nguyên tắc cần nhớ: (1) chọn device pool theo dữ liệu thị phần thật của app bạn, không theo cảm tính; (2) phân tầng test — PR-check chạy vài device đại diện, nightly/release chạy full pool — để cân bằng tốc độ, chi phí, độ phủ; (3) luôn test với locale=vi để bắt bug bản địa hóa mà đội dev dùng máy cao cấp thường bỏ sót. Với AWS nhớ chờ upload SUCCEEDED trước khi chạy; với Firebase tận dụng Robo test làm tấm lưới an toàn chi phí thấp. Nắm vững hai công cụ này, bạn có thể scale test mobile lên hàng trăm cấu hình mà không tốn một đồng cho phần cứng.