Kỷ lục phát triển máy đếm nhịp

Khi kiểm tra UI đa ngôn ngữ của Flutter, chúng tôi thấy “300 BPM” bị tách thành hai dòng

Chúng tôi kiểm tra hiển thị của SANGE Metronome bằng cách kết hợp 12 ngôn ngữ, 6 kích thước màn hình và 3 mức phóng đại chữ. Việc “300 BPM” xuống dòng và các thông báo lỗi dài đã dẫn đến sửa UI và xem lại các mục kiểm tra tự động.

công cộng cập nhật
  • Flutter
  • phát triển cá nhân
  • Hỗ trợ đa ngôn ngữ
  • Kiểm thử UI

Chúng tôi kiểm tra hiển thị trên màn hình nhỏ và khi đặt chữ lớn trong “SANGE Metronome – Luyện nhịp đơn giản”, ứng dụng được chúng tôi phát triển độc lập.

Một vấn đề được phát hiện là số trong “300 BPM” ở mục yêu thích bị tách thành “30” và “0”. Chữ không tràn ra khỏi màn hình. Tuy vậy, giá trị tốc độ trở nên khó đọc.

Cần kiểm tra riêng cả việc không phát sinh ngoại lệ bố cục và khả năng đọc được thông tin cần thiết.

Bài viết này trình bày các vấn đề hiển thị phát hiện qua kiểm thử widget bằng 12 ngôn ngữ và kiểm tra màn hình trên trình giả lập Android, cũng như cách đưa các phát hiện đó vào việc sửa lỗi và kiểm thử.

Tổng quan phần dưới màn hình chính bằng tiếng Pháp, Bồ Đào Nha Brazil, Indonesia, Thái, Việt và Nhật ở mức phóng đại chữ 130%
Tổng quan sáu màn hình sau khi sửa. Hàng trên từ trái: tiếng Pháp, Bồ Đào Nha Brazil và Indonesia. Hàng dưới: tiếng Thái, Việt và Nhật. Tên tiếng Đức trong các mục yêu thích là dữ liệu kiểm tra dùng chung cho mọi ngôn ngữ để thử tên dài.

Bố cục vừa với tiếng Nhật chưa chắc dùng được tương tự trong các ngôn ngữ khác

Màn hình máy đếm nhịp không chỉ hiển thị tốc độ mà còn có số phách, tên tiết tấu, âm lượng và tên mục yêu thích. Màn hình lưu cũng cần ô nhập liệu, giải thích lỗi cùng các nút Lưu và Hủy.

Ngay cả khi bố cục vừa lúc kiểm tra bằng tiếng Nhật, độ dài nhãn vẫn thay đổi khi dịch. Ví dụ, “12拍” trong tiếng Nhật và “12 Schläge” trong tiếng Đức đòi hỏi chiều rộng nút khác nhau.

Khi phóng to chữ hơn nữa, các thành phần đặt cạnh nhau không còn đủ chỗ. Vì vậy, thay vì chỉ đổi ngôn ngữ, chúng tôi quyết định kết hợp kích thước màn hình, mức phóng đại chữ và màn hình hiển thị khi kiểm tra.

Kiểm tra tự động với 12 ngôn ngữ, 6 kích thước và 3 mức phóng đại chữ

Trong kiểm thử widget, chúng tôi kết hợp các điều kiện sau. Kiểm thử widget kết xuất các thành phần giao diện Flutter trong môi trường kiểm thử để kiểm tra chúng.

Chiều kiểm trađiều kiện
Ngôn ngữTiếng Nhật, Anh, Tây Ban Nha, Bồ Đào Nha Brazil, Đức, Pháp, Hàn, Indonesia, Việt, Thái, Trung phồn thể và Ý
Kích thước logic, hướng dọc320×568、360×640、360×800、393×873、412×915、432×960
Mức phóng đại chữ100%, 130% và 200%
Màn hìnhMàn hình chính, số phách, chia nhỏ tiết tấu, cài đặt, chọn ngôn ngữ, lưu, quản lý mục yêu thích và danh sách yêu thích
12 ngôn ngữ × 6 kích thước × 3 mức phóng đại chữ × 8 màn hình = 1,728 điều kiện

Dữ liệu kiểm tra gồm 300 BPM, 12 phách, nốt móc kép, âm lượng 100% và ba mục yêu thích có tên dài. Trên màn hình lưu, chúng tôi cũng hiển thị lỗi trùng tên.

Mức phóng đại chữ được chỉ định bằng TextScaler.linear. Các mức 100%, 130% và 200% trong lần kiểm tra này là điều kiện phóng đại tuyến tính, không tái hiện đầy đủ mọi cách phóng to chữ qua cài đặt hệ điều hành trên thiết bị thật.

Chúng tôi cũng thu thập hình ảnh trên trình giả lập Android bằng bảy ngôn ngữ: Đức, Pháp, Bồ Đào Nha Brazil, Indonesia, Thái, Việt và Nhật. Chúng tôi không thử mọi tổ hợp kích thước, mức phóng đại và ngôn ngữ. Kích thước màn hình và mức phóng đại chữ được kiểm tra bằng tiếng Đức; sáu ngôn ngữ còn lại được kiểm tra với thiết lập 360×640 và mức 130%.

Trên trình giả lập, các thanh hệ thống làm giảm vùng khả dụng của ứng dụng. Ngoài kích thước đã thiết lập, chúng tôi ghi lại kích thước logic lúc kết xuất và kích thước bên trong SafeArea.

Điều chỉnh số cột của nút số phách để chữ vừa chỗ

Vấn đề đầu tiên được phát hiện là phần giải thích tốc độ và đơn vị số phách tràn ra bên phải. Trình giả lập Android cũng phát hiện RenderFlex overflow, khiến chúng tôi phải xem lại bố cục.

Các nút chọn số phách cũng từng có bố cục cố định bốn cột. Tuy nhiên, khi nhãn dịch dài hơn hoặc mức phóng đại chữ tăng, số cột đó không còn đủ chiều rộng.

Chúng tôi đo nhãn đã dịch bằng TextPainter rồi xác định số cột theo chiều rộng cần thiết, bao gồm cả mức phóng đại chữ. Khi không gian hẹp, chúng tôi giảm số cột và xếp các nút theo chiều dọc.

Màn hình chọn số phách sau khi sửa, với thiết lập 320×568 và tiếng Đức ở 100%, hiển thị các nút từ 1 đến 12 phách thành hai cột
Hiển thị ở 100% sau khi sửa. Trong điều kiện này, 12 nút có thể được xếp thành hai cột.
Màn hình chọn số phách với thiết lập 320×568 và tiếng Đức ở 200%, sau khi cuộn xuống. Các nút từ 7 đến 12 phách nằm trong một cột
Với cùng kích thước hiển thị ở mức 200%, bố cục chuyển sang một cột. Chúng tôi cuộn tới nút 12 phách và phần giải thích bên dưới. Mức phóng đại chữ và vị trí cuộn khác hình phía trên; cả hai đều là trạng thái sau khi sửa.

Trên màn hình chính, chúng tôi cũng xem lại bố cục ép tên tiết tấu dài vào hai cột hẹp, rồi xếp số phách và tiết tấu theo chiều dọc khi cần. Để khắc phục việc tách các số phách từ 10 đến 12, chúng tôi cho phép cả nhóm chỉ báo phách tự ngắt sang nhiều dòng.

“300” bị tách không nhất thiết gây ra ngoại lệ

Khi xem hình ảnh, chúng tôi phát hiện vấn đề ở các thẻ yêu thích với thiết lập 320×568 và mức phóng đại chữ 200%.

Vì các thẻ vẫn được xếp thành ba cột, “300” bị xuống dòng ngay giữa số. Ngay cả khi chữ nằm gọn trong vùng hiển thị, việc tách thành “30” và “0” vẫn khiến giá trị tốc độ khó đọc.

Chỉ kiểm tra ngoại lệ bố cục không phát hiện được vấn đề này.

Bản sửa điều chỉnh số cột của thẻ yêu thích theo mức phóng đại chữ. Trên màn hình nhỏ ở mức 200% trong lần kiểm tra này, chúng tôi chuyển sang một cột để các chữ số của tốc độ không bị tách.

Màn hình sau khi sửa với thiết lập 320×568 và tiếng Đức ở 200%, hiển thị mục yêu thích thành một cột ở phần dưới màn hình chính và số 300 BPM không bị tách
Mục yêu thích sau khi sửa. Phần cuối tên dài được rút gọn, còn các chữ số của tốc độ vẫn liền nhau. Do không lưu hình trước khi sửa trong điều kiện này, đây không phải so sánh cạnh nhau giữa trước và sau với cùng điều kiện.

Cùng với bản sửa, chúng tôi thêm vào kiểm thử tự động việc xác nhận BPM ba chữ số nằm trên một dòng. Dưới đây là đoạn trích của phần kiểm tra đó.

for (var card = 0; card < 3; card++) {
  final paragraph = tester.renderObject<RenderParagraph>(
    find.text('300  BPM').at(card),
  );
  expect(
    paragraph.getBoxesForSelection(
      const TextSelection(baseOffset: 0, extentOffset: 3),
    ),
    hasLength(1),
    reason:
        '$locale/$size/$scale favorite BPM must stay on one line',
  );
}

Chúng tôi xác nhận rằng dải ký tự tương ứng với “300” chỉ nằm trong một hộp kết xuất. Trong các bài kiểm thử đầy đủ, chúng tôi kiểm tra BPM của từng mục trong ba mục yêu thích và số phách từ 1 đến 12 trên màn hình chính.

Phương pháp này dành cho các chữ số được kết xuất bằng cùng một kiểu chữ trong lần kiểm tra này. Đây không phải phương pháp tổng quát để xác định xuống dòng trong văn bản trộn nhiều ngôn ngữ hoặc kiểu chữ khác nhau.

Cụ thể hóa các mục kiểm tra theo thông tin muốn hiển thị. Một kết quả hữu ích lần này là đưa những vấn đề phát hiện qua hình ảnh trở lại kiểm thử tự động để tiếp tục phát hiện chúng trong các thay đổi sau.

Có thể đọc giải thích lỗi và tiếp cận nút Lưu không?

Trên màn hình lưu, chúng tôi cũng xem lại giới hạn số dòng của thông báo lỗi.

Trước đây, văn bản bị giới hạn tối đa ba dòng, nhưng bản dịch dài có thể không vừa trên màn hình hẹp với chữ phóng to. Chúng tôi bỏ giới hạn số dòng để có thể cuộn và đọc toàn bộ giải thích.

Các nút Lưu và Hủy được đổi sang xếp dọc trên màn hình hẹp hoặc khi chữ lớn. Chúng tôi cũng thay đổi bố cục tiêu đề và nút đóng hộp thoại, cũng như tên cài đặt và giá trị đang chọn, để dành thêm chiều rộng cho chữ.

Màn hình lưu với thiết lập 320×568 và tiếng Đức ở 200%, sau khi cuộn xuống, hiển thị toàn bộ lỗi trùng tên cùng các nút Hủy và Lưu xếp dọc
Giải thích lỗi trùng tên cùng các nút Hủy và Lưu. Màn hình được chụp sau khi cuộn.

Chúng tôi cũng thêm kiểm tra khi nhập liệu. Trong kiểm thử widget, chúng tôi dành khoảng trống dưới 280 pixel logic tương đương bàn phím và xác nhận rằng sau khi cuộn, nút Lưu hiển thị phía trên vùng đó. Chúng tôi cũng kiểm tra thông báo lỗi không bị cắt do giới hạn số dòng.

Trên trình giả lập Android, chúng tôi thực sự đặt tiêu điểm vào ô nhập liệu và kiểm tra bố cục khi bàn phím mở. Tuy nhiên, các PNG thu thập lúc đó chỉ chụp màn hình Flutter, không bao gồm bàn phím của hệ điều hành. Hình ảnh hiển thị bình thường và khi nhập liệu được ghi riêng.

Kết quả sau khi sửa và phạm vi đã kiểm tra

Dưới đây là kết quả kiểm tra ngày 30 tháng 10 năm 2026.

MụcKết quả
Kiểm thử widget về hiển thịKhông có ngoại lệ bố cục trong 1,728 điều kiện. Các kiểm tra về việc tách chữ số, cắt bớt thông báo lỗi và khả năng tiếp cận nút Lưu cũng đạt trên các màn hình tương ứng
Toàn bộ kiểm thử Flutter121 bài kiểm thử đạt
Phân tích tĩnhKhông có vấn đề được báo cáo
Điều kiện màn hình trên trình giả lập Android280 điều kiện. Trong mỗi lần chạy, layoutErrors đều bằng 0
PNG đã thu thập478 hình ảnh, bao gồm trạng thái sau khi cuộn và trong khi nhập liệu

1,728 là số tổ hợp điều kiện hiển thị, còn 121 là tổng số bài kiểm thử Flutter đã chạy. Vì các bài kiểm thử lặp lại nhiều điều kiện hiển thị, hai con số này có ý nghĩa khác nhau.

478 là số PNG đã thu thập. Chúng tôi không chấm đạt hay không đạt bằng mắt cho từng hình ảnh; thay vào đó, chúng tôi chọn các màn hình chính để kiểm tra chữ bị cắt hoặc chồng lên nhau, số bị tách và hiển thị sau khi cuộn. Trên các màn hình chính tiếng Thái và tiếng Việt đã kiểm tra, không thấy ô vuông báo thiếu ký tự hay chữ chồng lên nhau.

Ngoài sáu kích thước tổng hợp, chúng tôi dùng sáu thiết lập hiển thị trên trình giả lập: Galaxy A16 5G, A06 4G, S24+, S23, Redmi 14C 4G và Pixel 9. Chúng tôi chuẩn bị 30 thiết lập theo mẫu thiết bị, nhưng lần này chỉ chạy sáu trong số đó.

Chúng tôi áp dụng độ phân giải và mật độ gần đúng phục vụ kiểm tra cho cùng một trình giả lập Android 14. Chúng tôi không tái hiện hệ điều hành riêng của nhà sản xuất, phông chữ hay lỗ camera, cũng không kiểm tra 30 mẫu trên thiết bị thật. Các bài kiểm thử Flutter chạy trên Windows; lần này cũng không chạy so sánh golden khớp từng pixel dành cho Linux.

Bản ghi này nói về kiểm tra hiển thị. Kết quả kết xuất, đặt tiêu điểm vào ô nhập liệu và cuộn không xác nhận rằng phát âm thanh hay quy trình lưu đã thành công.

Những điều cần tiếp tục kiểm tra khi thay đổi UI lần tới

Lần kiểm tra này giúp cụ thể hóa những mục chúng tôi muốn giữ lại trong kiểm thử hiển thị.

  • Không tách giữa các chữ số của giá trị như tốc độ và số phách.
  • Cho phép đọc đầy đủ các giải thích lỗi.
  • Giữ các nút cần thiết có thể tiếp cận khi phóng to chữ và khi nhập liệu.

Bằng cách đổi số cột theo kích thước chữ và bản dịch, đồng thời sử dụng bố cục dọc và cuộn, chúng tôi dành chỗ cho thông tin và thao tác cần thiết.

Lặp lại các điều kiện trong kiểm thử tự động và thêm những vấn đề nhận thấy qua hình ảnh đã kết xuất vào các mục kiểm tra. Việc duy trì quy trình này giúp chúng tôi xác nhận những vấn đề phát hiện lần này có tái diễn trong các thay đổi UI tiếp theo hay không.

← Tới danh sách các bài viết blog phát triển