Menu
ESC

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

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

Đang tải...

Cross-Browser Testing — chiến lược

Software Testing Fundamentals Bài 35/60

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

Hãy tưởng tượng bạn vừa ship một trang landing bán khóa học. Trên máy của bạn — Chrome trên Windows — mọi thứ đẹp long lanh: nút "Đăng ký" nằm gọn giữa màn hình, form nhập liệu mượt mà, ảnh banner load nhanh. Bạn tự tin báo với sếp là "xong rồi". Ba tiếng sau, một khách hàng nhắn qua fanpage: "Sao vào bằng iPhone, cái nút bị đè lên chữ, bấm không được?". Sếp mở Safari trên MacBook kiểm tra — đúng là banner vỡ layout, chữ tràn ra ngoài khung. Chỉ một khách hàng phàn nàn công khai, nhưng bạn không biết có bao nhiêu người đã lặng lẽ rời đi vì không đăng ký được.

Đó chính là lý do Cross-Browser Testing (kiểm thử đa trình duyệt) tồn tại. Ứng dụng web của bạn không chạy trên "một trình duyệt", mà chạy trên hàng chục tổ hợp trình duyệt, phiên bản, hệ điều hành và kích thước màn hình khác nhau. Người dùng Việt Nam đặc biệt đa dạng: có người dùng Chrome trên Android giá rẻ, có người dùng Safari trên iPhone cũ, có người vẫn dùng Cốc Cốc — trình duyệt nội địa chiếm thị phần không nhỏ. Nếu bạn chỉ test trên một môi trường, bạn đang mù trước phần lớn trải nghiệm thực tế.

Ở bài này, chúng ta sẽ không dừng ở việc "test trên nhiều trình duyệt cho vui". Chúng ta sẽ xây dựng một chiến lược cross-browser testing bài bản: chọn tổ hợp nào để test, ưu tiên ra sao, dùng công cụ gì, và làm sao để không tốn thời gian test những thứ không đáng. Đây là kỹ năng phân biệt một tester chuyên nghiệp với người chỉ "click thử vài trình duyệt".

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

Vì sao trình duyệt render khác nhau?

Gốc rễ của mọi khác biệt nằm ở rendering engine — bộ máy đọc HTML/CSS/JS và vẽ ra màn hình. Có ba engine lớn bạn cần thuộc lòng:

  • Blink — dùng bởi Chrome, Microsoft Edge, Cốc Cốc, Opera, Samsung Internet, và hầu hết trình duyệt Android. Đây là engine phổ biến nhất hiện nay.
  • WebKit — dùng bởi Safari trên macOS và iOS. Quan trọng: trên iOS, mọi trình duyệt đều bắt buộc dùng WebKit, kể cả Chrome trên iPhone. Nghĩa là Chrome iOS thực chất render bằng WebKit chứ không phải Blink. Đây là cái bẫy khiến rất nhiều tester nhầm.
  • Gecko — dùng bởi Firefox.
Vì mỗi engine triển khai chuẩn CSS/HTML theo cách hơi khác, và tốc độ hỗ trợ tính năng mới cũng khác, nên cùng một đoạn code có thể trông khác nhau. Một số điểm hay gây lệch:

  • CSS layout edge case: flexbox và grid có những hành vi biên (ví dụ gap trong flexbox, min-height bên trong flex item) mà Safari phiên bản cũ xử lý khác Chrome.
  • Font rendering: cùng một font, Safari và Chrome anti-alias khác nhau, khiến chữ trông đậm/mảnh khác, đôi khi làm layout xê dịch vài pixel — đủ để một dòng chữ bị xuống hàng ngoài ý muốn.
  • Ngày giờ và định dạng số: Date parsing trong JavaScript từng khác nhau giữa Safari và Chrome (Safari khắt khe hơn với chuỗi ngày không đúng chuẩn ISO).
  • Tính năng mới: các thuộc tính CSS mới hoặc API JS mới có thể chưa được hỗ trợ đồng đều — bạn phải tra cứu ở caniuse.com trước khi dùng.

Cross-browser không chỉ là "nhiều trình duyệt"

Một hiểu lầm phổ biến: cross-browser chỉ là mở Chrome, Firefox, Safari. Thực tế, một "tổ hợp test" (test configuration) gồm nhiều chiều:

  • Trình duyệt (Chrome, Safari, Firefox, Edge, Cốc Cốc...)
  • Phiên bản trình duyệt (bản mới nhất, bản cũ hơn 1-2 version)
  • Hệ điều hành (Windows, macOS, Android, iOS)
  • Kích thước màn hình / độ phân giải (desktop, tablet, mobile)
Nhân tất cả các chiều này lại, bạn có thể có hàng trăm tổ hợp. Không ai đủ thời gian test hết. Vì vậy trọng tâm của bài này là chiến lược chọn lọc — test đúng thứ đáng test.

Browser Matrix — công cụ nền tảng của chiến lược

Trái tim của cross-browser testing là Browser Matrix (ma trận trình duyệt): một bảng liệt kê các tổ hợp bạn cam kết hỗ trợ, thường phân theo mức ưu tiên:

  • Tier 1 (bắt buộc chạy hoàn hảo): những tổ hợp chiếm phần lớn traffic. Ví dụ Chrome Android mới nhất, Safari iOS mới nhất, Chrome Windows mới nhất.
  • Tier 2 (phải dùng được, chấp nhận lỗi nhỏ về thẩm mỹ): Firefox, Edge, Safari phiên bản trước.
  • Tier 3 (best-effort, không cam kết): trình duyệt cũ, thị phần rất nhỏ.
Nguyên tắc vàng: để dữ liệu quyết định, không phải cảm tính. Đừng đoán "chắc mọi người dùng Chrome". Hãy mở Google Analytics của chính sản phẩm bạn đang test, xem báo cáo Browser & OS trong 90 ngày gần nhất, rồi xây matrix từ số liệu thật. Sản phẩm cho dân văn phòng sẽ có nhiều desktop; sản phẩm cho người tiêu dùng phổ thông ở Việt Nam sẽ nghiêng nặng về mobile Android.

Tình huống thực tế

Tình huống 1: Sàn TMĐT và cái nút "Thanh toán" tàng hình trên Safari

Một startup thương mại điện tử ở TP.HCM (gọi là ShopViet) tung tính năng checkout mới. Đội dev test kỹ trên Chrome desktop, mọi thứ hoàn hảo, tỷ lệ hoàn tất giỏ hàng trong môi trường test đạt 100%. Nhưng sau khi lên production, tỷ lệ hoàn tất đơn hàng trên mobile tụt từ 68% xuống 52% chỉ trong hai ngày.

QA vào cuộc, mở Google Analytics và phát hiện: mức sụt giảm gần như toàn bộ đến từ Safari trên iOS. Kiểm tra thực tế trên iPhone, họ thấy nút "Thanh toán" bị một thanh công cụ dưới cùng của Safari che mất. Nguyên nhân kỹ thuật: dev dùng height: 100vh để căn nút xuống đáy màn hình, nhưng trên Safari iOS, 100vh tính cả phần thanh địa chỉ — khiến phần đáy thật sự bị đẩy ra ngoài vùng nhìn thấy. Trên Chrome desktop lỗi này vô hình.

Bài học: iOS Safari là "công dân hạng nhất" bắt buộc trong mọi Browser Matrix có traffic mobile ở Việt Nam, vì iPhone rất phổ biến ở phân khúc khách hàng có khả năng chi tiêu. Và 100vh là một trong những cái bẫy kinh điển — QA nên có checklist riêng cho các phần tử fixed/sticky ở đáy màn hình khi test trên iOS.

Tình huống 2: Cốc Cốc — trình duyệt mà nước ngoài không có

Một công ty fintech phục vụ thị trường Việt Nam làm cổng nạp tiền. Đội QA thuê dịch vụ test cloud của nước ngoài, chạy đủ Chrome, Firefox, Safari, Edge — tất cả xanh. Nhưng bộ phận chăm sóc khách hàng liên tục nhận báo lỗi: một nhóm người dùng bấm nút "Xác nhận OTP" thì trang trắng xóa.

Sau nhiều ngày, họ nhận ra điểm chung: những khách hàng này đều dùng Cốc Cốc. Trình duyệt nội địa này dựa trên Blink nhưng tích hợp sẵn trình chặn quảng cáo và một số script tối ưu riêng. Trong trường hợp này, bộ lọc của Cốc Cốc chặn nhầm một request tới domain của nhà cung cấp OTP vì domain đó trông giống tracker quảng cáo. Kết quả: JS lỗi, trang trắng.

Bài học: nếu sản phẩm phục vụ người Việt, Cốc Cốc phải nằm trong Browser Matrix Tier 1 hoặc Tier 2, dù các dịch vụ test cloud quốc tế thường không có sẵn nó. Đôi khi bạn buộc phải test thủ công trên máy thật cài Cốc Cốc. Đây là ví dụ điển hình cho nguyên tắc: matrix phải phản ánh người dùng thật của bạn, không phải danh sách trình duyệt "chuẩn quốc tế".

Tình huống 3: Firefox và ngày sinh không hợp lệ

Một nền tảng học trực tuyến (tương tự sản phẩm bạn đang làm) có form đăng ký yêu cầu nhập ngày sinh dạng dd/mm/yyyy. Trên Chrome, mọi thứ ổn. Nhưng người dùng Firefox báo rằng sau khi submit, hệ thống báo "ngày sinh không hợp lệ" dù họ nhập đúng.

QA điều tra và tìm ra: code JavaScript dùng new Date("25/12/1998") để parse. Chrome "đoán" được đây là ngày 25 tháng 12, nhưng Firefox (và Safari) tuân thủ chuẩn chặt chẽ hơn, không chấp nhận định dạng này và trả về Invalid Date. Vì dev chỉ test trên Chrome nên bug lọt lưới.

Bài học: những khác biệt cross-browser nguy hiểm nhất thường không phải lỗi giao diện dễ thấy, mà là lỗi logic JS ngầm — parse ngày, xử lý số thập phân, so sánh chuỗi có dấu tiếng Việt. Chúng chỉ lộ ra khi test đủ engine (Blink, WebKit, Gecko). Đây là lý do một Browser Matrix tốt phải phủ ít nhất một đại diện của mỗi engine.

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

Đây là quy trình bạn có thể áp dụng ngay cho bất kỳ dự án nào:

Bước 1 — Thu thập dữ liệu người dùng thật. Mở Google Analytics (hoặc công cụ analytics đang dùng) của sản phẩm. Xem báo cáo Browser, OS, Device, Screen Resolution trong 90 ngày gần nhất. Ghi lại phần trăm của từng tổ hợp. Nếu là sản phẩm mới chưa có dữ liệu, dùng số liệu thị trường Việt Nam làm điểm khởi đầu (nghiêng mobile, Chrome Android và Safari iOS chiếm đa số, có một lát Cốc Cốc).

Bước 2 — Xây Browser Matrix phân tier. Từ dữ liệu, gom các tổ hợp thành Tier 1/2/3. Nguyên tắc thực dụng: chọn số tổ hợp phủ khoảng 90-95% người dùng, đừng cố chạm 100%. Đảm bảo mỗi rendering engine (Blink, WebKit, Gecko) có ít nhất một đại diện.

Bước 3 — Xác định phạm vi test cho từng tier. Không phải mọi tổ hợp đều test như nhau. Với Tier 1: chạy toàn bộ test case chức năng + giao diện. Với Tier 2: chạy các luồng nghiệp vụ chính (đăng nhập, thanh toán, submit form) và kiểm tra layout không vỡ. Với Tier 3: chỉ smoke test — mở lên xem có dùng được không.

Bước 4 — Ưu tiên khu vực rủi ro cao. Không test lại toàn bộ trang trên mọi trình duyệt. Tập trung vào nơi dễ vỡ: layout phức tạp (flexbox/grid), phần tử fixed/sticky, form và validation, animation/transition, phần dùng CSS hoặc JS API mới. Trước khi test, tra caniuse.com để biết tính năng nào có rủi ro tương thích.

Bước 5 — Chọn công cụ phù hợp từng loại kiểm tra. Có ba nhóm công cụ:

  • DevTools responsive mode (Chrome/Firefox có sẵn): nhanh, tiện để kiểm tra sơ bộ kích thước màn hình — nhưng nhớ rằng đây chỉ là mô phỏng, KHÔNG thay được engine thật.
  • Thiết bị/máy thật: chính xác nhất, bắt buộc cho iOS Safari và Cốc Cốc. Một chiếc iPhone thật và một máy Android thật trong phòng QA là khoản đầu tư đáng giá.
  • Nền tảng test cloud (BrowserStack, LambdaTest, Sauce Labs): cho phép truy cập hàng trăm tổ hợp trình duyệt/OS thật qua trình duyệt, rất hữu ích khi cần phủ nhiều phiên bản mà không mua thiết bị.
Bước 6 — Tự động hóa phần lặp lại. Với các luồng quan trọng chạy đi chạy lại mỗi lần release, viết test tự động chạy trên nhiều engine (ví dụ dùng framework hỗ trợ chạy đa trình duyệt). Automation không thay được mắt người trong việc bắt lỗi thẩm mỹ, nhưng cực kỳ hiệu quả cho kiểm tra hồi quy chức năng trên nhiều engine cùng lúc.

Bước 7 — Ghi nhận và ưu tiên bug theo tier. Khi tìm ra lỗi, ghi rõ tổ hợp gặp lỗi (trình duyệt + version + OS + kích thước màn hình + độ phân giải). Bug trên Tier 1 phải sửa trước; bug thẩm mỹ nhỏ trên Tier 3 có thể ghi nhận nhưng hoãn.

Bước 8 — Rà soát matrix định kỳ. Thị phần trình duyệt thay đổi. Mỗi quý, xem lại analytics và cập nhật Browser Matrix. Trình duyệt hôm nay Tier 3 có thể biến mất, hoặc một phiên bản mới có thể cần thêm vào Tier 1.

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

Lỗi 1 — Tưởng DevTools responsive mode là test thật. Chế độ responsive trong Chrome chỉ đổi kích thước khung nhìn và user-agent, nhưng engine vẫn là Blink. Nó KHÔNG mô phỏng cách Safari WebKit render. Rất nhiều bug iOS bị bỏ sót vì tester chỉ "chỉnh cửa sổ Chroem thành iPhone". Mẹo: dùng responsive mode để test bố cục theo kích thước, nhưng luôn kiểm chứng iOS trên WebKit thật.

Lỗi 2 — Quên Cốc Cốc và các trình duyệt tích hợp adblock. Như tình huống fintech ở trên. Mẹo: nếu sản phẩm phục vụ người Việt, luôn có một máy cài Cốc Cốc để test các luồng gọi API tới domain bên thứ ba (thanh toán, OTP, tracking).

Lỗi 3 — Test mọi thứ trên mọi trình duyệt. Đây là cách nhanh nhất để kiệt sức và trễ deadline. Mẹo: dùng chiến lược phân tier + tập trung khu vực rủi ro. Đừng test lại footer tĩnh trên 15 trình duyệt.

Lỗi 4 — Không ghi rõ môi trường khi report bug. Một bug report "nút bị vỡ" mà không nói trình duyệt/OS/độ phân giải nào thì gần như vô dụng — dev không tái hiện được. Mẹo: luôn kèm đủ trình duyệt + version + OS + kích thước màn hình trong mọi bug cross-browser.

Lỗi 5 — Bỏ qua font tiếng Việt. Một số font web render dấu tiếng Việt (ẫ, ộ, ừ) khác nhau giữa các engine, có thể làm chữ chồng dấu hoặc lệch baseline. Mẹo: đưa một đoạn text tiếng Việt đầy đủ dấu vào bộ test giao diện, kiểm tra trên cả ba engine.

Mẹo tổng quát — dùng "graceful degradation" làm tư duy nền. Không phải mọi trình duyệt cần trải nghiệm y hệt. Miễn là chức năng cốt lõi dùng được ở Tier 2/3, một vài khác biệt về animation hay bo góc là chấp nhận được. Điều này giúp bạn phân bổ công sức hợp lý.

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

  • Xây Browser Matrix từ dữ liệu. Chọn một website Việt Nam bạn biết (hoặc chính sản phẩm bạn đang test). Giả định bạn có bảng phân bố: Chrome Android 40%, Safari iOS 30%, Chrome Windows 15%, Cốc Cốc 7%, Firefox 4%, Edge 3%, còn lại 1%. Hãy phân các tổ hợp này vào Tier 1/2/3, giải thích lý do, và nêu tổng phần trăm mà Tier 1 của bạn phủ.
  • Săn bug 100vh. Tìm hoặc tạo một trang có nút cố định ở đáy màn hình dùng height: 100vh. Mở trên Chrome desktop (responsive mode iPhone) rồi so với iPhone/Safari thật (hoặc cloud). Ghi lại điểm khác biệt và đề xuất cách sửa (gợi ý: tìm hiểu đơn vị dvh).
  • Kiểm chứng khác biệt engine bằng JS. Viết một đoạn thử new Date("25/12/1998") và log kết quả trên Chrome, Firefox, Safari. Ghi lại engine nào trả về Invalid Date. Viết lại code cho an toàn cross-browser (gợi ý: parse thủ công hoặc dùng định dạng ISO yyyy-mm-dd).
  • Viết checklist rủi ro. Dựa trên khu vực dễ vỡ đã học (flexbox, sticky, form, font tiếng Việt, animation), soạn một checklist 8-10 mục để rà soát trước mỗi lần release, kèm engine cần kiểm tra cho từng mục.

Tóm tắt

Cross-browser testing không phải là "mở thật nhiều trình duyệt và click bừa", mà là một chiến lược có kỷ luật. Điểm cốt lõi cần nhớ:

  • Khác biệt bắt nguồn từ ba rendering engine: Blink (Chrome, Edge, Cốc Cốc), WebKit (Safari — và mọi trình duyệt trên iOS), Gecko (Firefox). Matrix của bạn phải phủ đủ ba engine.
  • Trái tim của chiến lược là Browser Matrix phân tier, xây từ dữ liệu người dùng thật trong analytics, không phải cảm tính. Đừng cố phủ 100% — nhắm 90-95%.
  • Với thị trường Việt Nam, Safari iOSCốc Cốc là hai công dân bắt buộc mà nhiều đội hay bỏ sót.
  • DevTools responsive mode chỉ mô phỏng kích thước, KHÔNG thay được engine thật — iOS phải kiểm trên WebKit thật.
  • Tập trung công sức vào khu vực rủi ro cao (layout phức tạp, phần tử fixed/sticky, form, JS parse ngày/số, font tiếng Việt), tra caniuse.com trước khi dùng tính năng mới, và tự động hóa những luồng lặp lại.
  • Luôn ghi rõ môi trường trong bug report, và rà soát matrix định kỳ theo quý.
Nắm vững chiến lược này, bạn sẽ không còn bị bất ngờ bởi những tin nhắn "sao vào bằng iPhone không được" — vì bạn đã kiểm tra trước khi khách hàng làm điều đó.