为什么避免固定 sleep
固定 sleep 是脆弱测试的常见来源:时间设短了等待不足,机器一慢就假失败;设长了拖慢整个套件。更好的做法是等待可观测条件——元素可交互、接口返回、异步任务状态收敛——条件一成立立即继续,超时则失败并给出最后状态。现代框架都内置了条件等待机制,用它们替代 time.sleep 能同时改善稳定性与速度。
基本信息
| 问题本质 | 固定时长假设系统在确定时间内就绪,与真实环境不符 |
|---|---|
| 替代方案 | 条件轮询:成立即返回,超时带上最后状态 |
| 前端机制 | 框架级自动等待与 web-first 断言(如 Playwright) |
| 后端机制 | 封装带超时与间隔的等待函数,轮询状态接口 |
| 失败信息 | 超时异常要携带最后一次观察到的状态,便于定位 |
等待条件示例
等待条件示例
# 避免:time.sleep(3)
# 改为等待条件:
from playwright.sync_api import expect
expect(page.get_by_role("button", name="提交")).to_be_enabled()
# 后端轮询:条件成立立即返回,超时带最后状态
def wait_until(pred, timeout=10, interval=0.5):
... # 轮询 pred,超时抛异常并附上最后一次的观察值典型使用场景
- UI 自动化:等待元素可见、可点击再做下一步操作。
- 异步任务验证:轮询任务状态直至完成或超时。
- 接口幂等提交后:等待资源状态收敛再断言。
- CI 环境适配:慢机器与快机器用同一套条件等待逻辑。
- 数据同步:等待主从复制或缓存失效完成后校验一致性。
- 失败治理:把偶发失败从「加 sleep」改为「加条件」。
后端轮询场景可封装带超时与间隔的等待函数:条件成立即返回,超时则失败并带上最后状态。
等待条件要能真正判定目标状态:从「页面加载完成」改为「目标元素可交互」,条件选错等待再久也没用。
超时值集中配置:不同环境按网络与算力调整,不要散落在用例里各自硬编码。