AllianceProject Handbook
← Knowledge

Kiểm soát chất lượng

Automation test cho mobile và API

Hai câu hỏi: tự động hoá việc nào trước, và bộ test tự động phải đạt con số nào mới coi là xong. API trước mobile, mười luồng E2E là trần, chập chờn dưới 1%.

Cập nhật 14/09/2026chất lượngtestautomationCI
Nội dung bài
Thuật ngữ trong bài (31)

7 nhóm

việc automation trước tiên ở API

10 luồng

trần E2E mobile, không phải chỉ tiêu

< 1%

tỷ lệ chập chờn cho mỗi test

≤ 30 phút

cả bộ E2E chạy đêm

Bài này lấp phần nào

Chiến lược test chia tầng và tỷ trọng. Chuẩn test của dev nói dev phải viết gì và viết thế nào. Quality gate tự động nói cổng nào đặt ở đâu, chạy trong bao lâu. Ba bài đó đã có.

Phần còn thiếu là phần bài này: trong ngần ấy việc, cái nào đáng để máy làm, và làm xong thì lấy gì chứng minh là đủ.

Automation rẻ ở lần thứ N, không rẻ ở lần đầu

Viết một case tự động tốn gấp mấy lần làm tay case đó một lần. Nó chỉ có lãi khi được chạy lại nhiều lần mà không phải viết lại. Nên câu hỏi chọn việc không phải "case này có quan trọng không" — gần như case nào cũng quan trọng — mà là:

Case này sẽ chạy bao nhiêu lần trước khi bề mặt nó bám vào thay đổi và nó phải viết lại?

  1. Case ứng viên

    từ acceptance criteria, từ bug đã xảy ra thật

  2. Bốn câu hỏi sàng lọc

    bảng ngay dưới

  3. Đạt 3 trên 4

    viết tự động, gắn vào một cổng cụ thể

  4. Dưới 3 trên 4

    để người làm, hoặc bỏ hẳn

Bốn câu hỏi sàng lọc một case

Đáng để máy làm khi
Để người làm khi
Case chạy bao nhiêu lần mỗi tháng
Từ bốn lần trở lên — mỗi PR, mỗi đêm, mỗi release
Một lần rồi thôi, hoặc chỉ chạy khi có sự cố
Đầu ra có so sánh được bằng máy không
Mã trạng thái, số tiền, thứ tự, số bản ghi
Phải nhìn mới biết đúng: mượt, dễ hiểu, đẹp
Hỏng thì mất gì
Tiền, dữ liệu, quyền truy cập, niềm tin
Một chỗ hiển thị lệch, sửa được ở bản sau
Bề mặt bị test có ổn định không
Contract API, máy trạng thái, quy tắc tính tiền
Màn hình đang thiết kế lại, tính năng đang thử

Đạt ba trên bốn thì tự động hoá. Dưới ba thì không — và "không" ở đây là quyết định có chủ đích, không phải nợ kỹ thuật.

Một loại case bỏ qua cả bốn câu hỏi: bug đã lọt ra production. Luật đã có ở chuẩn test của dev — mỗi bug được sửa phải kèm một test tái hiện. Không sàng lọc, không bàn lại.

Cùng một luồng, ba chỗ test được — chọn chỗ rẻ nhất

Lấy đúng một yêu cầu của module Bán hàng: gửi lại cùng một khoá idempotency thì không được sinh đơn thứ hai.

Một lần chạy
Chạy ở cổng nào
Chứng minh được gì
Unit — hàm khử trùng theo khoá
khoảng 10 ms
Mỗi PR
Quy tắc khử trùng viết đúng
API — gửi lại cùng khoá năm lần
khoảng 2 giây
Mỗi PR
Server thật không tạo đơn thứ hai
E2E — bấm thanh toán, rút mạng, mở lại app
khoảng 3 phút
Chạy đêm
Cả chuỗi client, server và giao diện khớp nhau

Ba dòng đó không thay thế nhau — chúng chứng minh ba thứ khác nhau. Nhưng luật chọn thì rõ: leo lên tầng trên chỉ khi tầng dưới không chứng minh được điều đang cần. Một case E2E đỏ vì hàm làm tròn sai là một case đặt sai chỗ: nó lẽ ra chạy trong 10 ms và chỉ thẳng tên hàm.

Vì sao API đi trước mobile

Automation ở API

  • Một case chạy vài giây, đủ nhanh để nằm trong cổng PR
  • Không phụ thuộc thiết bị, phiên bản OS, tốc độ render
  • Vỡ khi contract đổi — mà contract đổi thì đằng nào cũng phải biết ngay
  • Chạy song song dễ, thêm case gần như không tốn thêm thời gian chờ

Automation ở giao diện mobile

  • Một case chạy hàng phút, phải có máy thật hoặc máy ảo giữ chỗ
  • Chập chờn vì chờ render, animation, mạng, hệ điều hành xen ngang
  • Vỡ khi đổi nhãn nút, đổi bố cục — thứ đổi hằng sprint
  • Chạy song song tốn thiết bị, mỗi case thêm vào đều đắt thật

Nghĩa là: phần lớn quy tắc nghiệp vụ nên được chứng minh ở tầng API, và giao diện mobile chỉ giữ lại những gì chỉ có giao diện mới chứng minh được.

Bảy nhóm phải automation ở API

1.Contract và schema

Response đúng hình dạng đã khai; thêm trường không làm vỡ client cũ; bỏ trường phải đi qua vòng deprecate. Đây là nhóm rẻ nhất và bắt được nhiều nhất, vì sinh thẳng từ đặc tả nên gần như không tốn bảo trì. Ràng buộc phiên bản nằm ở tương thích ngược.

2.Ma trận phân quyền

Mọi endpoint nhân với mọi vai trò, nhân với chính chủ và không phải chính chủ. Vài trăm ô — người làm tay chắc chắn bỏ sót, máy chạy hết trong vài giây. Luật của module Task là quyền kiểm ở server, nên ô trống trong ma trận này là một lỗ bảo mật chưa ai nhìn.

3.Ma trận lỗi

Thiếu trường, sai kiểu, chuỗi quá dài, token hết hạn, id không tồn tại — mỗi ca một mã trạng thái và một mã lý do cố định.

4.Tính tiền

Bảng ca biên: giá lẻ, nhiều mức giảm chồng nhau, thuế, số lượng lớn, làm tròn ở biên. Đây là bộ test có giá trị cao nhất trong toàn hệ thống, vì một đồng lệch là dừng release chứ không phải sai số cho phép.

5.Idempotency và gửi lại

Cùng một khoá gửi năm lần chỉ sinh một đơn, một tin nhắn. Ca "server đã nhận nhưng client chưa nhận phản hồi" bắt buộc nằm trong bộ này.

6.Máy trạng thái

Mọi chuyển hợp lệ chạy được, và ít nhất ba chuyển không hợp lệ bị từ chối kèm mã lý do — không phải bị chặn bằng cách ẩn nút.

7.Phân trang và dữ liệu lớn

Con trỏ không nhảy và không lặp khi có bản ghi chèn vào giữa; danh sách vài nghìn bản ghi không phá ngân sách thời gian. Đây là nhóm duy nhất cần bộ dữ liệu cỡ lớn dựng sẵn.

Kèm theo bảy nhóm: mỗi endpoint của luồng chính gắn một phép đo thời gian đáp ứng một request, so với ngưỡng API P95 ở performance budget. Đây không phải test tải — test tải là việc riêng, ở test tải và quy mô. Nó chỉ để bắt trường hợp một truy vấn mất chỉ mục làm endpoint chậm gấp mười lần mà mọi test chức năng vẫn xanh.

Mobile — ba tầng, và tầng đắt nhất phải ít

Tầng 1 — logic thuần, chạy trên CI, không cần máy

Máy trạng thái phía client, hàng đợi gửi khi offline, định dạng tiền và ngày, múi giờ, phân tích dữ liệu trả về. Hàng trăm case, tính bằng mili giây.

Tầng 2 — component và màn hình, không cần máy thật

Trạng thái rỗng, trạng thái lỗi, cỡ chữ hệ thống lớn nhất, dark mode, quyền bị từ chối thì màn hình hiện gì. Tầng bị bỏ quên nhiều nhất, rẻ hơn E2E hàng chục lần mà bắt đúng nhóm lỗi hay gặp.

Tầng 3 — E2E trên máy thật

Mười luồng, tính bằng phút, chạy đêm. Chỉ giữ thứ mà hai tầng dưới không chứng minh được.

Mười luồng E2E — đây là trần, không phải chỉ tiêu

Cài mới, mở tới màn hình chính

Hỏng ở đây thì mọi thứ sau đều vô nghĩa.

Đăng nhập, đăng xuất, token hết hạn giữa chừng

Bao gồm cả nhánh làm mới token im lặng.

Chat — gửi tin ở mạng chập chờn

Đúng một tin, đúng thứ tự, không mất.

Task — chuyển trạng thái, và bị chặn đúng khi thiếu quyền

Chặn phải đến từ server, kiểm qua giao diện.

Bán hàng — tạo đơn, thanh toán, lịch sử có đúng một đơn

Luồng đắt nhất nếu hỏng.

Mất mạng giữa chừng rồi có lại

Không mất dữ liệu đang nhập, không nhân đôi thao tác.

App bị hệ điều hành kill ở background rồi mở lại

Khôi phục đúng màn hình hoặc về màn hình an toàn.

Nâng cấp từ bản trước, mang theo dữ liệu cũ

Không bao giờ chỉ thử cài mới.

Deep link và push mở đúng màn hình

Cả khi app đang đóng lẫn khi đang mở.

Cold start trên máy low-end Tier 1

Đo theo ngân sách, không đo bằng cảm giác.

Muốn thêm luồng thứ mười một thì phải bỏ một luồng, hoặc chứng minh bộ chạy đêm vẫn dưới 30 phút. Danh sách này chọn theo chuẩn riêng của ba module, và máy chạy lấy theo ma trận thiết bị.

Bốn nhóm đặc thù mobile — máy tới đâu, người từ đâu

Kiểm thử đặc thù mobile liệt kê bốn nhóm kịch bản sinh ra phần lớn bug lọt ra production. Không nhóm nào tự động hoá được như nhau:

Máy làm được
Người vẫn phải làm
App lifecycle
Ép background và kill bằng lệnh, kiểm lưu và khôi phục state ở tầng 1
Quay video bằng chứng cho bốn flow rủi ro cao, và nhận ra bẫy cho kết quả xanh giả
Network chaos
Bóp băng thông, chặn response, tăng độ trễ bằng proxy — nhóm tự động hoá tốt nhất trong bốn nhóm
Cảm giác app ở sóng thật, nơi mạng chập chờn không theo kịch bản nào
Runtime permission
Cấp và thu hồi bằng lệnh, sáu trạng thái kiểm ở tầng 2
Dialog hệ điều hành đổi theo phiên bản OS — bám vào là vỡ mỗi lần OS lên đời
Upgrade và migration
Cài bản cũ, seed dữ liệu, cài đè, kiểm — bắt buộc tự động, người không lặp nổi mỗi release
Ca dữ liệu lạ chưa ai nghĩ ra, và dữ liệu thật của người dùng nội bộ

Chi tiết từng nhóm ở bài riêng: app lifecycle, network chaos, runtime permission, upgrade và migration.

Cần đạt được gì

Ba nhóm ngưỡng. Thiếu nhóm nào thì bộ automation vẫn chạy được, chỉ là không ai biết nó còn đáng tin hay không.

1. Độ phủ — automation phải chạm tới đâu

Ngưỡng
Đo bằng gì
Luồng sống còn có E2E
10 trên 10 luồng ở danh sách trên
Bảng đối chiếu luồng với mã test, xem lại mỗi release
Endpoint luồng chính có contract test
100%
Đối chiếu danh sách endpoint với đặc tả
Ô trong ma trận phân quyền
100% endpoint nhân vai trò
Báo cáo ma trận — ô trống là ô chưa ai test
Ca biên tính tiền
100% bảng ca biên đã chốt
Bảng ca biên nằm trong repo, không nằm trong trí nhớ ai
Coverage code mới trong PR
từ 80% trở lên
Cổng tầng 3, đã có sẵn ở quality gate
Bug production có test tái hiện
100%, không ngoại lệ
Phiếu bug chỉ đóng được khi kèm mã test

2. Sức khoẻ bộ test — vượt ngưỡng thì dừng thêm case mới, đi sửa

Ngưỡng
Vượt ngưỡng nghĩa là gì
Smoke suite
≤ 10 phút, pass 100%
Chọn sai case cho smoke — xem smoke test
Toàn bộ cổng PR
≤ 10 phút
Có test chậm đặt sai tầng, đẩy xuống bộ chạy đêm
Bộ API đầy đủ
≤ 15 phút, chạy mỗi PR
Thiếu chạy song song, hoặc test đang gọi dịch vụ thật
E2E chạy đêm
≤ 30 phút
Quá mười luồng, hoặc E2E đang làm việc của tầng dưới
Chập chờn của mỗi test
dưới 1% số lần chạy
Test đó hỏng — sửa trong 24 giờ hoặc tắt kèm phiếu theo dõi
Thời gian biết được vì sao đỏ
≤ 10 phút
Kết quả thiếu log, ảnh chụp màn hình, video hoặc dấu vết request
Thời gian sửa test vỡ mỗi tuần
dưới 20% quỹ thời gian test
Test đang bám vào bề mặt quá dễ đổi — chọn sai tầng

Ngưỡng cuối ít ai đo mà lại quyết định số phận của cả bộ test. Quá 20% nghĩa là automation đang ăn nhiều hơn nó trả, và nó sẽ bị bỏ trong một quý nữa.

3. Hiệu quả — thứ duy nhất chứng minh bộ test đáng tiền

Automation xanh không chứng minh gì cả. Hai con số sau mới chứng minh:

Bug bị bắt ở chặng nào

Đếm bug theo chặng phát hiện — dev tự test, cổng PR, QA, production. Tỷ trọng phải dịch dần sang trái qua từng quý. Đây chính là phép đo của tư duy shift left.

Bug lọt ra production mà một cổng lẽ ra đã bắt được

Đích là 0. Khác 0 thì đó là lỗi của cổng, không phải xui — mỗi ca phải kết thúc bằng một test mới hoặc một cổng được mở rộng.

Lộ trình đề xuất, bốn mốc

  1. Mốc 1 — khung và đường ray

    Bộ khung chạy được bằng một lệnh, dữ liệu tự seed và tự dọn, mười case smoke API, gắn vào CI mỗi PR. Đạt khi mở một PR bất kỳ và thấy kết quả trong 10 phút.

  2. Mốc 2 — API cho ba module

    Bảy nhóm ở trên, ưu tiên phân quyền và tính tiền. Đạt khi bộ API dưới 15 phút, chạy mỗi PR, không case nào chập chờn trong hai tuần liền.

  3. Mốc 3 — hai tầng dưới của mobile

    Unit logic thuần và component cho trạng thái rỗng, lỗi, cỡ chữ lớn, dark mode, quyền bị từ chối. Đạt khi coverage code mới giữ được từ 80% qua ba sprint liền.

  4. Mốc 4 — E2E và bộ chạy đêm

    Mười luồng trên máy Tier 1 thật, kèm kịch bản nâng cấp. Đạt khi bộ chạy đêm dưới 30 phút và ba tuần liền không có test chập chờn.

Thứ tự này cố ý: mobile E2E làm sau cùng, vì nó đắt nhất, và vì phần lớn quy tắc nghiệp vụ đã được ba mốc trước chứng minh xong ở chỗ rẻ hơn.

Dấu hiệu bộ automation đang lành hay đang mục

Đang lành

  • Đỏ nghĩa là có lỗi thật, và cả đội tin màu đỏ
  • Đọc tên test đỏ là biết hỏng cái gì, chưa cần mở code
  • Test vỡ khi hành vi đổi, không vỡ khi refactor
  • Thêm một case mới tốn vài phút, không tốn vài ngày
  • Mỗi test hỏng có đúng một người chịu trách nhiệm

Đang mục

  • "Chạy lại là xanh" trở thành câu nói quen của cả đội
  • Có test bị tắt mà không ai nhớ vì sao và từ bao giờ
  • Sửa một hàm làm vỡ 40 test — test đang bám vào chi tiết cài đặt
  • Số case tăng đều mỗi tháng, số bug bắt được thì không
  • Không ai dám xoá test nào, kể cả test không khẳng định điều gì

Sáu việc phải chốt trước khi coi là làm xong

Ai chốt

Chủ kỹ thuật chốt danh sách mười luồng E2E và bảng ca biên tính tiền. Mỗi nhóm API ghi tên một người, không để "team lo".

Chặn ở chặng nào

Lúc chốt acceptance criteria — case nào tự động hoá được thì ghi ngay tại đó, không đợi code xong mới nghĩ.

Máy hay người

Máy làm bảy nhóm API, hai tầng dưới của mobile, và kịch bản nâng cấp. Người làm khám phá, cảm giác mượt, dialog hệ điều hành, tích hợp thật với bên thứ ba.

Đo bằng số nào

Bảy ngưỡng sức khoẻ ở trên, cộng tỷ trọng bug bắt được trước production theo từng quý.

Bằng chứng ở đâu

Kết quả chạy đính vào pull request; E2E đỏ thì kèm video và dấu vết request. Bảng đối chiếu luồng với mã test nằm trong repo.

Hết giờ cắt gì

Cắt luồng E2E từ thứ sáu trở đi trước. Không bao giờ cắt bộ tính tiền, ma trận phân quyền và kịch bản nâng cấp.