AllianceProject Handbook
← Knowledge

Quy mô và hiệu năng

Test upgrade và data migration thế nào

Bài kiểm thử đặc thù mobile nói phải test update đè từ mọi version còn hỗ trợ. Bài này nói dựng dữ liệu version cũ bằng cách nào, cài đè ra sao cho không mất dữ liệu, và cách ép hỏng giữa lúc migration mà không phải đua với hệ điều hành.

Cập nhật 14/09/2026kiểm thửmobileshift left

Kiểm thử đặc thù mobile liệt kê tám kịch bản update và ba bước bắt buộc khi migration. Bài đó dừng ở phải làm gì. Bài này là phần làm bằng cách nào — dựng dữ liệu cũ, cài đè đúng cách, và ép hỏng đúng chỗ mình muốn thay vì chờ may rủi.

Dựng dữ liệu của version cũ bằng cách nào

Không có dữ liệu cũ thì không có gì để migrate, và test sẽ xanh vì nó chẳng làm gì cả.

File dữ liệu mẫu theo từng version schema

  • Mỗi lần đổi schema thì commit thêm một file database mẫu của version trước vào repo
  • Test nạp file đó vào, chạy migration, kiểm kết quả
  • Chạy được trong CI, tính bằng giây, không cần thiết bị
  • Rẻ nhất và bền nhất — nhưng chỉ đúng nếu file mẫu được sinh từ app thật, không phải viết tay

Cài bản cũ rồi dùng tay cho có dữ liệu

  • Cài APK hoặc IPA của version cũ, dùng vài ngày cho dữ liệu tự sinh ra
  • Bắt được cả thứ không nằm trong database: cache, file tạm, token, thiết lập
  • Không tự động hoá được, mỗi lần test lại phải dựng lại từ đầu
  • Vẫn phải làm trước mỗi release, vì mục trên không phủ được phần ngoài database

Cài đè, không cài mới

Android
iOS
Cài bản cũ lên máy sạch
adb install old.apk
xcrun simctl install <device> Old.app
Cài đè bản mới, **giữ dữ liệu**
adb install -r new.apk
xcrun simctl install <device> New.app — container dữ liệu giữ nguyên
Cài mới hoàn toàn, xoá sạch dữ liệu
adb uninstall <package> rồi cài lại
xcrun simctl uninstall <device> <bundle-id> rồi cài lại

Đừng mở lại bằng nút Run của IDE

Nhiều cấu hình Run gỡ app trước khi cài. Gỡ là mất dữ liệu, và bài test mất nghĩa mà vẫn báo xanh.

Ghi lại version nguồn ở mỗi lần chạy

Bảng version nguồn nhân kết quả update là bằng chứng duy nhất chứng minh đã phủ hết, lưu cùng release notes nội bộ.

Test chuỗi migration, không test từng bước

Mỗi bước đúng riêng lẻ không bảo đảm chuỗi bước đúng. Bước 2 đổi tên cột, bước 3 đọc tên cũ — chạy riêng thì cả hai đều xanh.

  1. Liệt kê mọi version còn hỗ trợ

    Con số này là một quyết định sản phẩm, phải có người chốt. Không chốt thì mặc định là "mọi version từng phát hành", và không ai test nổi.

  2. Với mỗi version, nạp file mẫu của chính version đó

    Không nạp file mẫu của version liền trước rồi suy ra.

  3. Chạy toàn bộ chuỗi migration tới schema hiện tại

    Một lần chạy, đi qua tất cả các bậc, đúng như máy user sẽ chạy.

  4. Kiểm dữ liệu sau khi chạy, không kiểm mã lỗi

    Đếm số bản ghi, đọc vài bản ghi ra so với dữ liệu gốc. Migration trả về thành công mà mất một cột là kết quả tệ nhất, vì nó im lặng.

  5. Chạy lại chuỗi đó lần thứ hai trên kết quả vừa xong

    Phải không đổi gì. Migration chạy hai lần mà hỏng nghĩa là một lần mở app bị gián đoạn cũng hỏng.

Ép hỏng giữa lúc migration

Đừng đua với hệ điều hành. Kill đúng lúc migration đang chạy là chuyện may rủi, mà may rủi thì không lặp lại được và không đưa vào CI được.

Chèn điểm hỏng có chủ đích

Thêm một chốt trong code test cho phép ném lỗi sau bước thứ k. Chạy lần lượt k bằng 1, 2, 3… tới hết. Mỗi lần: mở lại app, kiểm migration chạy tiếp được và dữ liệu còn nguyên.

Giả lập hết dung lượng cũng làm như vậy

Ném lỗi hết chỗ ghi ở từng bước, thay vì đi đổ đầy ổ đĩa máy thật. Rẻ hơn, lặp lại được, và phủ được đúng cái cần phủ: app phải fail an toàn, không xoá dữ liệu cũ trước khi ghi xong dữ liệu mới.

Vẫn chạy tay một lần trước release

adb shell am force-stop <package> giữa lúc migration trên máy thật, vài lần, ở máy yếu nhất. Nó bắt được thứ chốt test không bắt được: hỏng ở giữa một thao tác ghi chứ không phải ở ranh giới giữa hai bước.

Đổ đầy ổ đĩa khi thật sự cần

adb shell dd if=/dev/zero of=/data/local/tmp/fill bs=1M tới khi gần đầy, nhớ xoá sau khi xong. Chỉ làm khi nghi ngờ chính hệ thống file, không làm như thói quen.

Cái gì đẩy được vào CI

Chạy máy, mỗi pull request đụng schema

Chuỗi migration từ mọi version còn hỗ trợ, trên file dữ liệu mẫu. Đây là cổng chặn — pull request đổi schema mà không có test này thì không duyệt.

Chạy máy, cùng vòng đó

Vòng lặp ném lỗi sau bước thứ k. Số bước ít nên rẻ, và nó là thứ duy nhất chứng minh migration chạy lại được.

Chạy người, trước mỗi release

Cài bản cũ lên máy thật, dùng vài ngày, update đè. Ít nhất hai version nguồn: version liền trước và version cũ nhất còn hỗ trợ.

Không đẩy vào CI

Reinstall sau khi gỡ, và máy gần hết dung lượng thật. Để trong checklist release.

Giới hạn

Không có đường lùi

Trên mobile không rollback được binary đã cài, càng không rollback được dữ liệu đã hỏng. Ở 500.000 user, tỷ lệ mở app thất bại 0,2% trong 24 giờ sau update là 1.000 người mất dữ liệu local — không có nút nào bấm để trả lại.