Product Management
Đăng nhập
ESC

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

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

Bài 46 — Mobile Analytics & Event QA

Đã đọ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 tưởng tượng công ty của bạn vừa chi 500 triệu đồng cho một chiến dịch quảng cáo Tết trên TikTok để kéo người dùng tải app. Ba tuần sau, đội marketing họp khẩn: dashboard Firebase báo tỷ lệ chuyển đổi từ "mở app" sang "hoàn tất mua hàng" chỉ có 2%, thấp thảm hại. Cả team hoảng loạn, chuẩn bị cắt ngân sách, đổ lỗi cho creative. Nhưng rồi một bạn QA phát hiện ra sự thật: sự kiện purchase_completed bị gắn nhầm — nó chỉ bắn (fire) khi người dùng bấm nút "Xác nhận" ở màn hình cuối, nhưng trên iOS phiên bản 2.4 nút đó gọi sai callback nên event không bao giờ được gửi đi. Doanh số thật vẫn tốt; chỉ có dữ liệu là sai. Chiến dịch suýt bị giết oan vì một con số dối trá.

Đây chính là lý do Mobile Analytics & Event QA tồn tại. Trong thế giới sản phẩm số hiện đại, gần như mọi quyết định — từ ưu tiên tính năng, phân bổ ngân sách, đến đánh giá A/B test — đều dựa trên dữ liệu hành vi người dùng thu thập qua các "sự kiện" (event) bắn từ app. Nếu dữ liệu này sai, mọi quyết định phía trên nó đều sai theo. Người ta hay nói "garbage in, garbage out". Là QA, bạn là tuyến phòng thủ cuối cùng đảm bảo rằng những con số mà ban lãnh đạo nhìn vào phản ánh đúng thực tế. Đây là một mảng testing ít được dạy bài bản nhưng cực kỳ giá trị — và làm tốt nó sẽ khiến bạn nổi bật giữa đám đông QA chỉ biết kiểm thử UI.

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

Analytics event là gì?

Một analytics event là một bản ghi mô tả một hành động hoặc trạng thái xảy ra trong app, được app gửi lên máy chủ phân tích. Mỗi event thường gồm ba phần:

  • Tên event (event name): ví dụ screen_view, add_to_cart, checkout_started.
  • Thuộc tính (properties/parameters): cặp key-value mô tả ngữ cảnh, ví dụ product_id: "SP1234", price: 299000, currency: "VND".
  • User/session context: thông tin về người dùng và phiên, như user_id, device_model, app_version, platform.
Ngoài event, còn có user properties (thuộc tính người dùng) — những đặc điểm gắn lâu dài với một người dùng như membership_tier: "gold" hay city: "Ha Noi", dùng để phân khúc (segment) khi phân tích.

Các công cụ phổ biến ở Việt Nam

Trong bối cảnh Việt Nam và Đông Nam Á, bạn sẽ thường xuyên gặp những công cụ sau:

  • Firebase Analytics (Google): miễn phí, tích hợp sẵn trong hệ sinh thái Firebase, là lựa chọn mặc định của phần lớn startup Việt. Mạnh về event cơ bản và liên kết với Crashlytics, Remote Config. Nhược điểm: giao diện phân tích funnel/cohort không sâu bằng công cụ chuyên biệt, và có độ trễ báo cáo (thường vài giờ).
  • Mixpanel: rất mạnh về event-rich analysis — cho phép định nghĩa nhiều event và thuộc tính chi tiết, phân tích hành vi tinh vi. Nhiều công ty product-led ở VN dùng cho phân tích sâu.
  • Amplitude: tập trung vào funnel (phễu chuyển đổi) và cohort (nhóm người dùng theo thời gian), rất được ưa chuộng bởi các đội growth. Giao diện trực quan cho việc dựng phễu nhiều bước.
  • AppsFlyer / Adjust: đây là các MMP (Mobile Measurement Partner), chuyên đo lường attribution — tức xác định người dùng đến từ nguồn quảng cáo nào. Cực kỳ phổ biến ở VN cho các app thương mại điện tử và game vì gắn với chi tiêu ads. (Attribution sâu là chủ đề của Bài 47, ở đây ta chỉ đề cập ở mức nó cũng nhận event.)
Điều quan trọng cần hiểu: một app thực tế thường gửi event đồng thời tới nhiều công cụ thông qua một lớp trung gian. Nhiều đội dùng Segment hoặc một tracking wrapper tự viết để bắn một event một lần rồi phân phối tới Firebase, Amplitude, AppsFlyer cùng lúc. Điều này có hệ quả QA quan trọng: một event sai có thể làm hỏng dữ liệu ở nhiều hệ thống, và cùng một event có thể xuất hiện với tên khác nhau ở mỗi nơi.

Tracking plan — "hợp đồng" của event

Trái tim của Analytics QA là tracking plan (hay analytics spec / taxonomy). Đây là tài liệu — thường là một Google Sheet hoặc file trong công cụ như Avo, Iteratively — liệt kê chính xác:

  • Mỗi event tên là gì, gửi khi nào (trigger).
  • Có những thuộc tính nào, kiểu dữ liệu ra sao (string, number, boolean), bắt buộc hay tùy chọn.
  • Giá trị hợp lệ (ví dụ payment_method chỉ được là momo, zalopay, card, cod).
Tracking plan chính là "hợp đồng" (contract) mà QA dùng làm chuẩn để đối chiếu. Không có tracking plan, bạn không thể test analytics một cách có hệ thống — bạn chỉ đang đoán. Nếu công ty bạn chưa có, việc thúc đẩy tạo ra nó đã là một đóng góp lớn.

Vì sao analytics QA khó?

Khác với test UI (nhìn thấy được) hay test API (có response rõ ràng), analytics event là thứ vô hình — nó âm thầm bắn đi trong nền. Bạn không thể "nhìn" nó bằng mắt thường. Phải dùng công cụ chuyên biệt (DebugView, Charles Proxy, logcat...) để "soi" các event đang được gửi. Đây là điểm khiến nhiều QA bỏ qua mảng này, và cũng là lý do dữ liệu analytics ở rất nhiều công ty đầy lỗi mà không ai biết.

Tình huống thực tế

Tình huống 1: Sự kiện mua hàng bị bắn hai lần ở Tiki-clone

Một sàn thương mại điện tử (gọi là ShopViet) phát hiện báo cáo doanh thu trong Amplitude cao hơn doanh thu thật trong hệ thống backend khoảng 18%. Team growth dùng con số Amplitude để tính ROAS (return on ad spend) và đang định tăng mạnh ngân sách vì "quảng cáo hiệu quả".

QA vào cuộc, mở DebugView của Firebase và bật Charles Proxy, thực hiện một giao dịch mua thử. Kết quả: event purchase bắn hai lần trong vòng 300ms. Nguyên nhân: màn hình xác nhận đơn hàng có gắn tracking trong hàm onResume() của Activity, và trên Android khi người dùng quay lại từ màn hình thanh toán, onResume() được gọi lại lần nữa. Kết quả là mỗi đơn hàng bị đếm gần hai lần trong nhiều trường hợp.

Bài học: Analytics QA phải kiểm tra không chỉ "event có bắn không" mà còn "event có bắn đúng SỐ LẦN không". Duplicate event là một trong những lỗi phổ biến và nguy hiểm nhất vì nó thổi phồng mọi chỉ số. Đặc biệt cảnh giác với event gắn vào lifecycle callback (onResume, viewDidAppear) — chúng dễ bị gọi lại.

Tình huống 2: Thiếu thuộc tính khiến phễu thanh toán "mù"

Một ví điện tử fintech (gọi là PayNhanh) muốn phân tích tại sao người dùng bỏ giữa chừng khi nạp tiền. Họ dựng funnel trong Amplitude: topup_started → topup_method_selected → topup_confirmed → topup_success. Nhưng khi phân tích, họ không thể trả lời được câu hỏi "phương thức nạp nào (MoMo, ngân hàng, thẻ) bị bỏ nhiều nhất?" vì event topup_method_selected không kèm thuộc tính method.

QA đã bỏ sót điều này vì trong lần test trước, họ chỉ kiểm tra event có xuất hiện đúng tên, không đối chiếu đủ danh sách thuộc tính bắt buộc trong tracking plan. Việc bổ sung method phải chờ tới sprint sau và mất thêm hai tuần dữ liệu quý giá trong đúng mùa cao điểm.

Bài học: Event bắn đúng tên nhưng thiếu thuộc tính quan trọng thì cũng như không — dữ liệu mất chiều phân tích. QA phải đối chiếu từng thuộc tính với tracking plan, không chỉ tên event. Một event nghèo thuộc tính là một cơ hội phân tích bị đánh mất vĩnh viễn cho khoảng thời gian đó.

Tình huống 3: PII lọt vào event gây rủi ro pháp lý

Một app đặt xe ở Đông Nam Á vô tình gửi số điện thoại và email người dùng dưới dạng plaintext trong thuộc tính của event ride_completed, do lập trình viên tiện tay gắn cả object user vào tham số. Dữ liệu này chảy vào Firebase và Amplitude — các bên thứ ba. Khi công ty tiến hành audit tuân thủ (compliance), họ phát hiện đã vi phạm chính sách bảo mật của chính mình và tiềm ẩn vi phạm quy định bảo vệ dữ liệu cá nhân (như Nghị định 13/2023 về bảo vệ dữ liệu cá nhân ở Việt Nam).

Bài học: Analytics QA còn có trách nhiệm về quyền riêng tư (privacy). Cần kiểm tra rằng không có PII (Personally Identifiable Information — số điện thoại, email, CMND/CCCD, địa chỉ chính xác) bị gửi trong event trừ khi đã được ẩn danh/băm (hash) và được phép. Đây là loại lỗi âm thầm nhưng hậu quả pháp lý và uy tín rất lớn.

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

Đây là quy trình thực chiến để QA một tính năng có gắn analytics:

Bước 1 — Lấy tracking plan làm chuẩn. Trước khi test, mở tracking plan cho tính năng bạn phụ trách. Liệt kê tất cả event kỳ vọng, trigger của chúng, và bảng thuộc tính (tên, kiểu, bắt buộc/tùy chọn, giá trị hợp lệ). Nếu không có tracking plan, hãy làm việc với PM/analyst để tạo tối thiểu một bản cho phạm vi bạn test.

Bước 2 — Chuẩn bị công cụ quan sát. Tùy nền tảng và công cụ:

  • Firebase: bật DebugView bằng lệnh adb shell setprop debug.firebase.analytics.app <package_name> (Android) hoặc thêm arg -FIRDebugEnabled (iOS). DebugView hiển thị event gần như realtime.
  • Chặn network: dùng Charles Proxy hoặc mitmproxy để bắt các request HTTP gửi tới app-measurement.com (Firebase), api.mixpanel.com, api2.amplitude.com... Đây là cách "chân lý" nhất vì bạn thấy đúng payload gửi đi.
  • Android logcat: lọc theo tag FA (Firebase Analytics) để xem event trong log.
Bước 3 — Thực hiện hành động và quan sát. Với mỗi event trong tracking plan, thực hiện đúng hành động kích hoạt nó, rồi kiểm tra trong công cụ quan sát:
  • Event có bắn không?
  • Có bắn đúng một lần không (trừ khi thiết kế cho phép nhiều)?
  • Tên event có khớp chính xác (kể cả chữ hoa/thường, dấu gạch dưới)?
Bước 4 — Xác thực thuộc tính (validate properties). Với mỗi event đã bắn, đối chiếu từng thuộc tính:
  • Đủ các thuộc tính bắt buộc chưa?
  • Kiểu dữ liệu đúng chưa (price phải là số 299000 chứ không phải chuỗi "299.000đ")?
  • Giá trị nằm trong danh sách hợp lệ chưa (currency phải là "VND" chứ không phải "vnd" hay "đồng")?
  • Có PII lọt vào không?
Bước 5 — Kiểm tra các trường hợp biên (edge cases).
  • Xoay ngang màn hình, tắt/mở lại app giữa chừng — event có bị bắn lặp không?
  • Mất mạng khi thao tác — event có được lưu lại và gửi sau khi có mạng (offline queue) không, hay mất luôn?
  • Thao tác nhanh liên tục (double-tap) — có tạo event trùng không?
Bước 6 — Kiểm tra ở lớp phân tích (downstream). Sau khi event bắn đúng ở client, xác nhận nó đến đúng ở dashboard. Đôi khi client đúng nhưng có bộ lọc/transform ở Segment hay ở phía server làm sai lệch. Dựng thử một funnel đơn giản để chắc chắn dữ liệu dùng được cho phân tích thật.

Bước 7 — Ghi nhận và báo cáo. Lập bảng kết quả: event nào PASS, FAIL, hoặc thiếu. Với lỗi analytics, hãy đính kèm ảnh chụp payload thật (từ Charles/DebugView) — bằng chứng cụ thể giúp dev sửa nhanh và tránh tranh cãi.

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

Lỗi thường gặp:

  • Chỉ test "event có bắn không", bỏ qua thuộc tính và số lần. Đây là lỗi phổ biến nhất. Event đúng tên nhưng sai thuộc tính hoặc bị duplicate vẫn làm hỏng dữ liệu.
  • Không có/không dùng tracking plan. Test analytics mà không có chuẩn đối chiếu thì chỉ là cảm tính. Bạn sẽ bỏ sót event thiếu và không phát hiện được lệch chuẩn.
  • Quên test hai nền tảng riêng biệt. iOS và Android thường có code tracking riêng. Rất hay gặp cảnh event đúng trên Android nhưng sai/thiếu trên iOS (như tình huống mở đầu). Luôn test cả hai.
  • Nhầm giữa debug data và production data. Event bắn ở chế độ debug thường bị lọc riêng và không vào báo cáo chính. Ngược lại, đừng làm bẩn dữ liệu production bằng các phiên test — dùng tài khoản test hoặc thuộc tính environment: "test" để lọc.
  • Bỏ qua chuẩn hóa tên (naming convention). Trộn lẫn snake_case và camelCase, hay đặt AddToCart chỗ này add_to_cart chỗ kia, khiến dữ liệu bị phân mảnh — analyst tưởng là hai event khác nhau.
Mẹo thực chiến:

  • Dùng Charles Proxy làm "nguồn chân lý". Khi DebugView và log mâu thuẫn, payload HTTP thật trên proxy là bằng chứng cuối cùng về cái gì thực sự được gửi đi.
  • Tạo checklist tái sử dụng. Với mỗi event, dùng một mẫu kiểm tra cố định (bắn/đúng số lần/tên/thuộc tính/PII). Điều này biến công việc mơ hồ thành có hệ thống.
  • Kết bạn với data analyst. Họ là người tiêu thụ dữ liệu bạn kiểm; họ biết chỉ số nào quan trọng nhất và có thể phát hiện lệch chuẩn từ phía dashboard mà bạn không thấy từ client.
  • Nghĩ tới tự động hóa dần. Với các event quan trọng, có thể viết assertion trong test Appium/Espresso để kiểm tra event bắn ra (đọc từ log hoặc mock endpoint), biến analytics QA thành một phần của regression.

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

  • Dựng tracking plan mini. Chọn một app bạn hay dùng (ví dụ Shopee, Grab, hoặc một app tự phát triển). Viết tracking plan cho luồng "thêm sản phẩm vào giỏ → thanh toán": liệt kê 4–6 event kỳ vọng, trigger, và bảng thuộc tính (tên, kiểu, bắt buộc/tùy chọn) cho mỗi event.
  • Soi event thật. Cài Firebase DebugView (hoặc dùng Charles Proxy trên một app demo có Firebase). Thực hiện vài thao tác và ghi lại: event nào bắn ra, kèm những thuộc tính gì. Đối chiếu với tracking plan bạn vừa viết — có event nào thiếu, thừa, hay sai kiểu dữ liệu không?
  • Săn lỗi duplicate. Với app demo, thử xoay màn hình, tắt/mở lại app, hoặc double-tap nút thao tác. Quan sát xem có event nào bị bắn lặp không. Ghi lại kịch bản tái hiện.
  • Kiểm tra PII. Rà soát payload của 3 event bất kỳ và kiểm tra xem có thuộc tính nào chứa email, số điện thoại, hoặc thông tin định danh cá nhân dạng plaintext không. Viết một bug report giả định nếu phát hiện.

Tóm tắt

Analytics & Event QA là việc đảm bảo các sự kiện hành vi mà app gửi lên các công cụ như Firebase, Mixpanel, Amplitude, AppsFlyer phản ánh đúng những gì người dùng thực sự làm — vì mọi quyết định sản phẩm và ngân sách đều dựa trên dữ liệu này. Nền tảng của công việc là tracking plan đóng vai trò hợp đồng để đối chiếu. QA giỏi không chỉ kiểm "event có bắn không" mà kiểm cả số lần bắn (tránh duplicate), độ đầy đủ và đúng kiểu của thuộc tính, sự đồng nhất giữa iOS và Android, và không rò rỉ PII. Công cụ chính là Firebase DebugView, Charles Proxy/mitmproxy và logcat để "soi" thứ vô hình đó. Ba tình huống thực tế — event mua hàng bị đếm hai lần, phễu thanh toán "mù" vì thiếu thuộc tính, và PII lọt ra ngoài — cho thấy hậu quả rất thật: quyết định sai, mất cơ hội phân tích, và rủi ro pháp lý. Làm tốt mảng này, bạn không chỉ bảo vệ chất lượng app mà còn bảo vệ chính la bàn ra quyết định của cả công ty.

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