Product Management
Đăng nhập
ESC

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

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

Bài 54 — Geolocation & Map Testing

Đã đọc 0/14 mục · còn khoảng 12 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

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

Hãy hình dung bạn đang test app Grab. Người dùng mở app lên, đặt một chuyến xe từ Quận 1 đến sân bay Tân Sơn Nhất. Trên bản đồ, chấm xanh của tài xế phải di chuyển mượt mà, khoảng cách và thời gian dự kiến (ETA) phải cập nhật liên tục, và khi tài xế tới nơi đón, app phải nhận ra điều đó. Chỉ một tính năng "nhỏ" là định vị (geolocation) thôi mà kéo theo cả một chuỗi phụ thuộc: quyền truy cập vị trí, độ chính xác GPS, tốc độ cập nhật, xử lý khi mất tín hiệu, và render bản đồ.

Với một QA mobile ở Việt Nam, geolocation không phải là tính năng "phụ" mà là xương sống của gần như mọi app đình đám: Grab, Be, Gojek (gọi xe), ShopeeFood, GrabFood, BeFood (giao đồ ăn), rồi các app giao hàng như Giao Hàng Nhanh, J&T, hay app bản đồ, du lịch, hẹn hò. Nếu bạn không biết test vị trí cho ra hồn, bạn sẽ bỏ lọt những bug khiến người dùng bị tính sai cước, tài xế đi lạc, hay đơn giao đến sai địa chỉ.

Điểm khiến geolocation testing khó là: nó phụ thuộc vào thế giới thực. Bạn không thể yêu cầu cả team ra đường chạy xe để test. Bạn cần biết cách giả lập vị trí (mock location), giả lập lộ trình di chuyển (route simulation), và kiểm soát điều kiện GPS ngay trên bàn làm việc. Đó chính là nội dung của bài này.

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

Nguồn định vị: không chỉ có GPS

Nhiều bạn mới nghĩ "vị trí = GPS", nhưng thực tế mobile OS lấy vị trí từ nhiều nguồn kết hợp, gọi chung là location providers:

  • GPS (satellite): chính xác nhất (3–5m ngoài trời) nhưng chậm khi khởi động (cold start), tốn pin, và gần như vô dụng trong nhà hoặc giữa các tòa nhà cao (urban canyon như khu Landmark 81).
  • Network / Wi-Fi positioning: dựa vào các điểm phát Wi-Fi và trạm phát sóng đã biết. Nhanh, hoạt động trong nhà, nhưng độ chính xác thấp hơn (có thể lệch vài chục đến vài trăm mét).
  • Cell tower (cellular): chỉ ước lượng thô theo trạm BTS, sai số lớn (hàng trăm mét đến vài km).
  • Fused Location (Android): Google gộp các nguồn trên lại thành một API duy nhất, tự chọn nguồn tốt nhất theo bối cảnh và mức độ chính xác bạn yêu cầu.
Là QA, bạn phải hiểu app đang yêu cầu độ chính xác nào. Một app gọi xe cần high accuracy (bật GPS), còn một app thời tiết chỉ cần biết bạn đang ở thành phố nào thì dùng độ chính xác thấp để tiết kiệm pin.

Độ chính xác, độ trôi và tần suất cập nhật

Ba thông số bạn phải nắm khi đọc dữ liệu vị trí:

  • Accuracy (bán kính độ chính xác): mỗi điểm định vị đi kèm một con số, ví dụ "chính xác trong vòng 12 mét". Con số càng nhỏ càng tốt. App tốt phải biết bỏ qua các điểm có accuracy tệ (ví dụ > 50m) để tránh nhảy lung tung.
  • GPS drift (độ trôi): khi đứng yên, tọa độ vẫn dao động nhẹ quanh vị trí thật. App phải làm mượt (smoothing), nếu không chấm định vị sẽ "nhảy múa" dù bạn không đi đâu cả.
  • Update frequency (tần suất): bao lâu app xin vị trí một lần. Gọi xe cần cập nhật gần như liên tục (1–2 giây); app ghi chú địa điểm chỉ cần một lần khi lưu.

Quyền truy cập vị trí (permission model)

Đây là phần dễ ra bug nhất và bạn phải test tất cả các trạng thái:

  • While Using the App (chỉ khi dùng app): vị trí chỉ chạy khi app đang mở foreground.
  • Always (luôn luôn): cho phép cả khi app chạy nền — cần cho theo dõi tài xế đang giao hàng.
  • Ask Next Time / Only Once (chỉ lần này): iOS cho phép cấp quyền một lần rồi hỏi lại lần sau.
  • Denied (từ chối): app phải xử lý mượt, hiển thị thông báo hướng dẫn bật lại, chứ không được crash hay treo màn hình trắng.
  • Precise vs Approximate Location (iOS 14+ / Android 12+): người dùng có thể tắt "vị trí chính xác", chỉ cho vị trí gần đúng. App gọi xe mà chỉ nhận approximate thì tài xế đón sai chỗ — đây là ca test rất hay bị bỏ sót.

Mock location — công cụ vàng của QA

Bạn không thể ra đường để test. Thay vào đó dùng mock location:

  • iOS Simulator: menu Debug → Location cho phép chọn tọa độ cố định, hoặc chạy các preset như City Run, Freeway Drive để giả lập di chuyển.
  • Xcode + file GPX: bạn nạp một file GPX chứa dãy tọa độ để giả lập một lộ trình thật, ví dụ tuyến từ Bến Thành đến Thảo Cầm Viên.
  • Android Emulator: Extended Controls → Location, có thể set điểm đơn hoặc import file GPX/KML và "play" theo tốc độ tùy chọn.
  • Real device Android: bật Developer Options → chọn "Mock location app", rồi dùng app như Lockito hoặc kết nối Appium để bơm tọa độ giả.
  • Appium: lệnh driver.set_location(lat, lon, altitude) cho phép tự động hóa việc đặt vị trí trong test script.

Tình huống thực tế

Tình huống 1 — Grab và cú "teleport" của tài xế

Một team QA test app gọi xe (giả định tên nội bộ là "RideX", quy mô tương tự Grab). Trong sprint, dev vừa đổi thư viện bản đồ. Tester dùng Android Emulator, import file GPX mô phỏng chuyến từ Quận 3 đến Quận 7, cho tài xế "chạy" với tốc độ 40 km/h.

Kết quả: chấm tài xế trên bản đồ thỉnh thoảng nhảy vọt vài trăm mét rồi quay lại — hiện tượng "teleport". Đào sâu, họ phát hiện app không lọc các điểm GPS có accuracy tệ (> 60m). Trên emulator, một vài điểm giả lập bị gán accuracy kém, và app hiển thị luôn thay vì bỏ qua. Ngoài đời, hiện tượng này xảy ra khi tài xế đi qua đường hầm sông Sài Gòn hoặc khu nhiều nhà cao tầng.

Bài học: đừng chỉ test "chấm có chạy không". Phải test app lọc điểm nhiễu và làm mượt lộ trình. Con số cần theo dõi: bao nhiêu % điểm bị nhảy > 100m so với điểm trước trong khi tốc độ báo cáo chỉ 40 km/h (tức về mặt vật lý không thể).

Tình huống 2 — ShopeeFood và ETA sai giờ cao điểm

Một QA test app giao đồ ăn (bối cảnh giống ShopeeFood). Yêu cầu: khi tài xế nhận đơn, app tính ETA (thời gian tài xế tới quán rồi tới khách). Tester dùng iOS Simulator với preset di chuyển, đặt vị trí quán ở khu Phú Nhuận và khách ở Bình Thạnh.

Bug phát hiện: khi tài xế dừng đèn đỏ hoặc kẹt xe (mock location đứng yên vài phút), ETA vẫn tính như thể tài xế đang chạy, khiến khách thấy "còn 5 phút" suốt 15 phút. Ngược lại, khi tester bật preset Freeway Drive (tốc độ cao bất thường trong nội thành), ETA rút xuống phi lý.

Họ bổ sung test case: mô phỏng vị trí đứng yên kéo dài và tốc độ đột biến, kiểm tra app có cập nhật lại ETA hợp lý không. Đồng thời test khi tài xế rời lộ trình (đi sai đường) app có tính lại tuyến (re-routing) không.

Bài học: geolocation không tách rời khỏi logic nghiệp vụ như ETA, re-routing, geofencing. Test phải phủ cả các trạng thái "bất thường của đời thực": đứng yên, kẹt xe, đi sai đường, mất sóng giữa chừng.

Tình huống 3 — App du lịch và cú test permission bị bỏ quên

Một app tìm địa điểm ăn uống gần đây (local search, kiểu Foody/Google Maps mini) ra bản cập nhật iOS. QA chỉ test với quyền "Allow While Using". App chạy tốt, lên store.

Vài ngày sau, hàng loạt review 1 sao: người dùng iOS 14+ đã chọn "Approximate Location" (vị trí gần đúng). App vẫn hiển thị "quán gần bạn" nhưng thực ra lệch cả cây số, đưa ra danh sách quán ở phường khác. Tệ hơn, một nhóm người dùng từ chối quyền thì app hiện màn hình trắng vì thiếu xử lý fallback.

Team bổ sung một ma trận test permission: chạy qua các trạng thái Precise/Approximate, Allow Once/While Using/Denied, và bật/tắt Location Services toàn hệ thống. Họ cũng thêm case người dùng thay đổi quyền khi app đang chạy (vào Settings tắt vị trí rồi quay lại app).

Bài học: bug định vị nghiêm trọng nhất thường không nằm ở "vị trí đúng chưa" mà ở permission và fallback. Một QA giỏi luôn test cả kịch bản người dùng nói "không".

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

Đây là quy trình test geolocation cho một app có bản đồ, bạn có thể áp dụng trực tiếp:

  • Xác định yêu cầu định vị của app. Hỏi dev/PO: app cần độ chính xác nào, cập nhật tần suất bao nhiêu, có chạy nền không, có dùng geofencing không. Đọc cả phần khai báo quyền trong Info.plist (iOS) và AndroidManifest.xml (Android) để biết app xin quyền gì và có mô tả lý do (usage description) rõ ràng chưa.
  • Test ma trận quyền (permission matrix). Lần lượt: Allow While Using, Allow Once, Always (nếu có), Denied, Precise on/off. Ở mỗi trạng thái kiểm tra: app có hiển thị đúng UI hướng dẫn không, có crash không, có fallback hợp lý không (ví dụ cho nhập địa chỉ thủ công khi bị từ chối).
  • Đặt vị trí tĩnh (static location). Dùng Simulator/Emulator set một tọa độ cụ thể (ví dụ Hồ Gươm: 21.0287, 105.8524). Kiểm tra app định vị đúng chỗ, marker đúng vị trí, khoảng cách tính đúng.
  • Mô phỏng lộ trình di chuyển (route simulation). Chuẩn bị file GPX cho một tuyến thật (ví dụ Bến Thành → Tân Sơn Nhất). Import vào Emulator/Xcode, cho chạy ở nhiều tốc độ. Quan sát: chấm di chuyển mượt không, ETA cập nhật hợp lý không, có teleport/giật không.
  • Test các điều kiện GPS xấu. Giả lập accuracy kém, mất tín hiệu giữa chừng (set về không có vị trí), vào "hầm" (dừng cập nhật vài giây rồi tiếp tục). App phải không nhảy lung tung, không crash, hiển thị trạng thái "đang tìm vị trí" nếu cần.
  • Test geofencing (nếu có). Nhiều app kích hoạt hành động khi vào/ra một vùng: "tài xế đã đến điểm đón", "bạn đang gần cửa hàng". Mock vị trí đi vào và ra khỏi bán kính geofence, kiểm tra event kích hoạt đúng, không kích hoạt lặp (bounce) khi đứng ngay ranh giới.
  • Test vị trí nền (background location). Với app cần theo dõi khi ở nền (giao hàng đang chạy), đưa app xuống nền, tiếp tục mô phỏng di chuyển, kiểm tra app vẫn cập nhật (nếu có quyền Always) và tiêu thụ pin ở mức chấp nhận được.
  • Test tự động hóa bằng Appium. Trong script, dùng driver.set_location(lat, lon, alt) để đặt vị trí trước khi kiểm tra UI (ví dụ assert marker đúng, assert text "Cách bạn 1.2 km"). Có thể bơm một dãy tọa độ trong vòng lặp để mô phỏng di chuyển và verify từng bước.
  • Test trên thiết bị thật khi có thể. Mock location tốt nhưng không thay thế hoàn toàn thế giới thực. Cuối chu kỳ, đi thực địa một tuyến ngắn để đối chiếu hành vi drift, cold start và chuyển vùng thật.

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

  • Chỉ test với happy path GPS chuẩn. Đời thực đầy nhiễu. Luôn test accuracy kém, mất sóng, đứng yên, đi sai đường.
  • Quên trạng thái Approximate Location. iOS 14+/Android 12+ cho phép vị trí gần đúng — rất nhiều bug định vị lọt lưới vì QA quên bật trạng thái này.
  • Không test permission thay đổi khi đang chạy. Người dùng có thể vào Settings tắt vị trí giữa chừng rồi quay lại. App phải phản ứng, không được giữ chấm cũ như thật.
  • Lẫn lộn tọa độ (lat, lon). Kinh điển: nhầm vĩ độ với kinh độ khiến điểm rơi ra giữa biển hoặc sang tận châu Phi. Việt Nam: vĩ độ ~8–23, kinh độ ~102–110. Nhớ mốc này để phát hiện lỗi ngay.
  • Quên xóa mock location trước khi test khác. Real device Android nếu để "mock location app" bật, các test sau sẽ dùng vị trí giả mà bạn không hay.
  • Bỏ qua cold start GPS. Lần đầu bật GPS có thể mất 10–30 giây mới có vị trí. Test app hiển thị gì trong khoảng "đang chờ" đó.
  • Mẹo geofence bounce: khi đứng ngay ranh giới, GPS trôi qua lại làm event vào/ra bắn liên tục. Đây là ca test bắt buộc cho app có geofencing — kiểm tra app có hysteresis (đệm) không.
  • Mẹo về timezone và vị trí: một số app suy ra múi giờ hoặc quốc gia từ vị trí. Test mock vị trí ở nước ngoài (ví dụ Singapore, Bangkok) xem app có xử lý đúng tiền tệ, ngôn ngữ, ưu đãi theo vùng không.
  • Mẹo tiết kiệm công: dựng sẵn một bộ file GPX cho vài tuyến VN thường dùng (nội thành HN, nội thành HCM, có hầm, có cao tốc) để tái sử dụng cho mọi lần regression.

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

  • Dựng bộ mock location: Trên iOS Simulator và Android Emulator, đặt vị trí tĩnh tại Hồ Gươm (21.0287, 105.8524) rồi tại chợ Bến Thành (10.7721, 106.6980). Xác nhận app bạn đang test hiển thị đúng.
  • Tạo và chạy file GPX: Viết một file GPX mô phỏng tuyến Bến Thành → Tân Sơn Nhất (khoảng 8–10 điểm). Import vào Xcode hoặc Emulator, cho chạy và quan sát chấm di chuyển. Ghi lại: có teleport không, ETA (nếu app có) cập nhật thế nào.
  • Viết ma trận permission: Lập bảng test với các cột trạng thái (Allow While Using, Allow Once, Denied, Precise off) và các dòng kịch bản (mở app lần đầu, đổi quyền khi đang chạy, tắt Location Services toàn máy). Điền kết quả kỳ vọng cho từng ô, rồi thực thi.
  • Test điều kiện xấu: Mô phỏng mất tín hiệu GPS 10 giây giữa lộ trình. Kiểm tra app có hiện trạng thái chờ, có nhảy chấm không, có tính lại tuyến khi có tín hiệu lại không.
  • Tự động hóa với Appium: Viết một test dùng set_location đặt vị trí cách một địa điểm mẫu đúng 1 km, rồi assert app hiển thị chuỗi khoảng cách hợp lý (ví dụ "1.0 km" hoặc "cách 1 km"). Thử thêm một dãy tọa độ để mô phỏng tiến lại gần và verify khoảng cách giảm dần.

Tóm tắt

Geolocation là trái tim của phần lớn app mobile ăn khách ở Việt Nam — gọi xe, giao đồ ăn, giao hàng, tìm địa điểm. Là QA, bạn không ra đường được, nên mock location (Simulator/Emulator, file GPX, Appium set_location, app mock trên máy thật) là công cụ sống còn.

Ba trụ cột cần nhớ: (1) hiểu nguồn định vị và độ chính xác — GPS, Wi-Fi, cell, fused, accuracy, drift; (2) test ma trận quyền và fallback — Precise/Approximate, Allow/Denied, thay đổi khi đang chạy, đây là nơi ẩn nhiều bug nghiêm trọng nhất; (3) test các trạng thái đời thực — di chuyển, đứng yên, kẹt xe, mất sóng, đi sai đường, geofence bounce, cold start.

Đừng bao giờ dừng ở "chấm có chạy không". Hãy hỏi: app xử lý ra sao khi vị trí xấu, khi người dùng từ chối, khi tài xế kẹt xe giữa cầu Sài Gòn. Đó mới là chất lượng thật mà người dùng cảm nhận được.

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