Flaky test là kiểu test lúc pass lúc fail dù code sản phẩm không đổi. Hôm nay CI đỏ, bấm re-run lại xanh. Lâu dần, team nhìn fail rồi mặc định: “chắc flaky thôi” — nguy hiểm nhất là bug thật cũng bị bỏ qua.
Bài này sẽ đi từ: 🔍 nhận biết → 🧩 nguyên nhân → 🛠️ cách fix → ✅ checklist phòng tránh.
Flaky test = test cho kết quả không ổn định trên cùng một phiên bản code / cùng điều kiện logic.
📌 Ví dụ:
Chạy 10 lần: ✅✅❌✅✅❌✅✅✅❌
Local pass 💻 nhưng CI fail 🤖
Fail nhiều hơn khi chạy parallel ⚡
🎯 Tác hại:
⏳ tốn thời gian điều tra & rerun
🚫 làm CI “đỏ giả”, chặn pipeline
🧠 giảm niềm tin vào automation
😵 team “lờn cảnh báo”
Bạn nên nghi ngờ flaky nếu thấy:
🔁 Re-run cùng commit nhưng kết quả khác nhau
🧩 Chạy lẻ thì pass, chạy cả suite thì fail
⚡ Fail nhiều hơn khi bật parallel
⏱️ Fail kiểu: timeout / element not found / stale element / intercepted
🕒 Fail theo thời điểm: gần nửa đêm, cuối tháng, giờ cao điểm
Dấu hiệu
“element not found”, “timeout”, “expected X but got Y”
UI chưa render xong / API chưa trả về / animation chưa kết thúc
Gốc rễ
Test “chạy nhanh hơn app”
Dùng sleep() thay vì chờ điều kiện thật
Dấu hiệu
Test chạy chung fail, chạy riêng pass
Fail theo thứ tự chạy (order-dependent)
Gốc rễ
Dùng chung account, chung record, chung dữ liệu
Không cleanup sau test
DB/cache/config bị ảnh hưởng từ test trước
Dấu hiệu
Fail tăng vọt khi bật parallel
Test tạo/xóa/sửa dữ liệu thường fail
Gốc rễ
Nhiều test cùng update 1 resource
Test A xóa dữ liệu khi test B đang dùng
Dấu hiệu
Timeout, 5xx, DNS, rate limit
Fail theo giờ cao điểm hoặc theo region
Gốc rễ
Phụ thuộc service ngoài không kiểm soát
CI network chậm hơn local
Dấu hiệu
“stale element reference”, “element intercepted”
UI thay đổi layout nhẹ là test fail
Gốc rễ
Locator dựa vào index/text dynamic/CSS dễ đổi
Click khi element chưa “clickable”
Dấu hiệu
Fail gần nửa đêm, DST, cuối tháng
Fail ở case lịch, hạn sử dụng, filter theo ngày
Gốc rễ
Dùng thời gian thật (now()) không freeze
Random không seed
Re-run cùng commit 5–10 lần
Nếu fail không ổn định → khả năng cao là flaky
Nếu fail 100% → nhiều khả năng là bug thật hoặc test sai logic
⏱️ Timeout/element → timing/sync
🧼 Duplicate/không tìm thấy data → shared state / data bẩn
⚡ Fail khi parallel → race condition
🕒 Fail theo ngày giờ → time/timezone
UI test: screenshot + video + console log
API test: request/response + status + timing
DB/Integration: dump state trước/sau test
CI: lưu artifact để so sánh giữa lần pass/fail
Chạy test đó độc lập
Chạy test đó + nhóm liên quan để tìm phụ thuộc thứ tự
✅ Nên:
Chờ spinner biến mất
Chờ button enabled/clickable
Chờ text/state đúng (ví dụ status chuyển “Success”)
Chờ request hoàn tất (nếu framework hỗ trợ network wait)
❌ Tránh:
sleep(2) / Thread.sleep() “cho chắc” → chậm và vẫn flaky
🔍 Nguyên tắc: Chỉ chờ đúng thứ bạn cần để assert đúng.
✅ Nên:
Tạo data riêng cho mỗi test (🆔 UUID/prefix theo build)
Cleanup sau test (teardown) hoặc rollback transaction
Nếu có thể: môi trường automation riêng, không share với dev/manual
📌 Công thức bền:
Given: tạo user/data unique
When: thao tác
Then: assert
Finally: cleanup
✅ Nên:
Không dùng chung account/record
“Namespace hóa” dữ liệu theo build ID / worker ID
Tag nhóm test: @parallel-safe vs @serial
🧱 Nếu bắt buộc dùng tài nguyên chung:
Dùng lock/mutex (ở tầng test runner hoặc DB)
Hoặc chạy nhóm đó serial để đảm bảo ổn định
✅ Nên:
Mock/stub third-party (SMS/Email/Payment/Maps…)
Tăng timeout hợp lý trên CI (CI thường chậm)
Retry có kiểm soát cho lỗi transient (timeout/502/503)
⚠️ Lưu ý:
♻️ Retry chỉ là “băng cá nhân”
Nếu test chỉ “xanh nhờ rerun”, suite vẫn đang bệnh
✅ Nên:
Dùng data-testid / accessibilityId / automationId
Tránh locator theo index hoặc text dynamic
Click/typing chỉ khi element visible + enabled + không bị che
✨ Bonus:
Tắt animation trong test env (nếu làm được) để giảm “intercepted/stale”
✅ Nên:
Freeze time hoặc inject clock (fake time)
Seed random cố định
Cố định timezone trên CI và environment test
Khi CI đỏ liên tục, ưu tiên là giữ pipeline chạy ổn trước:
🧯 Quarantine flaky tests (tạm tách khỏi gate bắt buộc)
📊 Đo flaky rate (fail 1/50 khác fail 10/50)
🎯 Fix test fail nhiều nhất trước (impact cao)
✅ Bỏ quarantine và theo dõi 1–2 tuần
⛔ Không lạm dụng sleep()
🔁 Luôn wait theo điều kiện thật
🆔 Data unique + cleanup/rollback
🔀 Không phụ thuộc thứ tự chạy
⚡ Chia nhóm parallel-safe / serial
🏷️ Locator có test-id ổn định
📸 CI lưu log/screenshot/video/artifact
👤 Có owner + deadline cho flaky ticket
Flaky test thường đến từ:
⏱️ đồng bộ kém + 🧼 data không cô lập + ⚡ parallel không an toàn + 🌐 môi trường không ổn định + 🕒 time/random không deterministic.
Chỉ cần bạn nhìn đúng dấu hiệu và fix đúng nhóm, test suite sẽ xanh ổn định và đáng tin hơn rất nhiều ✅
You need to login in order to like this post: click here
YOU MIGHT ALSO LIKE