CYBERSOFT
Đăng nhập

Selenium chống flaky: wait, đồng bộ hoá và chiến lược retry

Chuyên nâng caoSeleniumNâng cao
🗓 1 tháng trước19 phút đọc·👁 1,672 lượt xem👤 366 người đọc

Đào sâu implicit vs explicit vs fluent wait, ExpectedConditions, điều kiện tuỳ biến, stale element, race condition trong SPA và cách dùng retry đúng liều để đưa tỉ lệ flaky về gần không.

1. Flaky test là gì và vì sao nó chết người

Một test flaky là test có lúc xanh có lúc đỏ trên cùng một đoạn code không đổi. Trong hệ thống lõi của một ngân hàng số, nơi mỗi lần release chạm tới giao dịch tiền thật, một bộ test hay đỏ ngẫu nhiên còn nguy hiểm hơn không có test: nó khiến đội mất niềm tin, bắt đầu bấm chạy lại cho tới khi xanh, và cuối cùng vô hiệu hoá luôn cả những lần đỏ thật sự là bug. Nguyên nhân số một của flaky trong Selenium là đồng bộ hoá sai: test chạy nhanh hơn tốc độ ứng dụng cập nhật DOM. Bài này đào sâu ba loại wait, ExpectedConditions, điều kiện tuỳ biến, stale element, race condition và chiến lược retry để đưa tỉ lệ flaky về gần không.

⚠️ Đừng bao giờ chữa flaky bằng cách tăng time.sleep. Nó chỉ giấu triệu chứng, làm bộ test chậm dần, và vẫn gãy trên máy tải cao.

2. Implicit wait: tiện nhưng nhiều bẫy

Implicit wait được đặt một lần cho cả driver bằng driver.implicitly_wait(10). Sau đó mọi lệnh findElement sẽ tự poll DOM tối đa 10 giây trước khi ném NoSuchElementException. Nghe rất tiện, nhưng nó có ba nhược điểm nghiêm trọng. Thứ nhất, nó chỉ chờ phần tử có mặt trong DOM, không chờ phần tử hiển thị hay có thể click, nên bạn vẫn dính ElementNotInteractableException. Thứ hai, nó áp lên mọi lời gọi kể cả những chỗ bạn cố ý muốn kiểm tra phần tử KHÔNG tồn tại, làm test kiểm tra vắng mặt chậm chạp một cách vô lý. Thứ ba, trộn nó với explicit wait gây cộng dồn thời gian khó lường. Nhiều đội trưởng thành chọn tắt hẳn implicit wait và chỉ dùng explicit.

3 loại wait trong Selenium Implicit wait đặt 1 lần / driver poll đến khi element có mặt áp cho MỌI findElement chỉ chờ presence, không chờ clickable đừng trộn với explicit! Explicit wait WebDriverWait + condition ExpectedConditions chờ đúng trạng thái cần visible · clickable · text → được KHUYẾN NGHỊ Fluent wait explicit + tinh chỉnh withTimeout / pollingEvery ignoring(Exception) retry custom condition chống stale element
Ba loại wait và khi nào dùng loại nào
python
# Đặt implicit wait (nếu dùng) — CHỈ đặt một lần, đừng trộn explicit
driver.implicitly_wait(0)   # nhiều đội đặt 0 để tắt hẳn, dùng explicit thay thế

# Hệ quả: kiểm tra một phần tử vắng mặt sẽ RẤT chậm nếu implicit > 0
elements = driver.find_elements(By.CSS_SELECTOR, ".error")  # trả [] ngay nếu implicit=0
assert len(elements) == 0, "Không được có lỗi hiển thị"

3. Explicit wait và ExpectedConditions

Explicit wait là công cụ chủ lực. Bạn tạo một WebDriverWait với timeout và chu kỳ poll, rồi truyền vào một điều kiện. Selenium cung cấp sẵn một bộ ExpectedConditions bao trùm hầu hết nhu cầu: presence_of_element_located chờ phần tử vào DOM, visibility_of_element_located chờ nó hiển thị, element_to_be_clickable chờ nó vừa hiển thị vừa bật, text_to_be_present_in_element chờ nội dung, staleness_of chờ một phần tử cũ biến mất, và alert_is_present chờ hộp thoại. Chọn đúng điều kiện cho đúng ý định là mấu chốt: nếu bạn định click thì chờ element_to_be_clickable chứ đừng chỉ chờ presence, vì phần tử có trong DOM chưa chắc đã bấm được.

python
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

wait = WebDriverWait(driver, 15, poll_frequency=0.5)

wait.until(EC.presence_of_element_located((By.ID, "app")))            # có trong DOM
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".modal")))  # hiển thị
btn = wait.until(EC.element_to_be_clickable((By.ID, "pay")))         # bấm được
btn.click()
wait.until(EC.text_to_be_present_in_element(
    (By.CSS_SELECTOR, ".status"), "Thành công"))                     # có nội dung
💡 Đặt timeout hào phóng (10–15s) nhưng chu kỳ poll ngắn (0.3–0.5s). Test sẽ tiếp tục ngay khi điều kiện đúng, nên timeout lớn không làm test chậm nếu app phản hồi nhanh.
🔒

Nội dung bị khoá

Bạn đang xem bản xem trước. Đăng nhập để mở khoá toàn bộ bài viết và tất cả tài liệu Tester/QA.

Đã xem 25% nội dung
  • Đọc trọn vẹn mọi bài viết
  • Lưu bài & ghi chú cá nhân
  • Theo dõi tiến độ đã đọc
  • Luyện phỏng vấn, ISTQB, Mock
Đăng nhập để đọc tiếp

Chưa có mã? Lấy mã qua Fanpage / Zalo CyberSoft.

0

💬 Bình luận (0)

Bạn có thể đọc mọi bình luận. Đăng nhập để bình luận

Chưa có bình luận nào. Hãy là người đầu tiên!