Web 自动化测试总是超时?聊聊等待、超时和异步加载

0 阅读8分钟

页面明明可以正常操作,自动化测试却提示元素找不到,或者等待超时。同一条用例,第一次失败,重新运行又通过了。

遇到这种情况,很多人第一反应是等待时间太短了,再多加几秒。

增加等待时间有时确实有效,但也会让测试变得越来越慢,甚至掩盖真正的问题。想让 Web 界面自动化测试更稳定,首先需要弄清楚,测试到底在等什么,又该等到什么时候?

为什么 Web 自动化测试容易超时?

现代 Web 应用大量使用异步加载。页面打开后,浏览器可能还在请求接口、渲染组件,或者更新局部内容。比如进入订单列表,页面框架可能已经显示,但订单数据还在加载。点击保存按钮后,页面出现成功提示,新记录却还没有更新到列表中。

这里有三个容易混淆的状态:

  • 页面已加载: 浏览器完成某个加载阶段,但异步请求可能仍在进行。
  • 元素可操作: 目标已经出现,且没有被禁用、遮挡,可以正常交互。
  • 业务已完成: 操作产生了预期结果,例如订单创建成功、审批状态更新。

如果测试在错误的时机执行下一步,就容易出现偶发失败。这也是 Flaky Test(不稳定测试)的常见原因之一。

UI1.png

常见的等待机制,有什么区别?

处理等待问题,首先要了解不同等待方式的特点。

1. 固定等待

最简单的方式是让脚本暂停一段指定时间,例如:

await page.waitForTimeout(3000);

但页面如果 1 秒就准备好了,测试仍要等满 3 秒。如果需要 5 秒,等待 3 秒又不够。固定等待适合部分动画和短暂过渡,但不宜大量使用。

2. 条件等待

相比固定等待,条件等待会持续检查目标状态,在规定时间内满足条件就继续执行。

例如,点击保存按钮前,可以等待按钮从禁用状态变为可操作。对于异步加载的页面,可以通过观察 Loading 或遮罩层是否消失,来判断是否适合继续执行。

假设页面可能需要 1~5 秒加载订单列表。使用条件等待,加载快时可以提前继续,加载慢时也有一定缓冲,不需要每次都等满固定时间。

3. 超时控制

无论等待什么条件,都应该设置明确的时间上限。

如果目标元素始终没有出现,或者按钮一直不可操作,测试就需要在达到上限后结束当前等待并报告失败。

同时,不同操作的合理等待时间也可能不同。例如普通按钮点击通常不需要很长时间,但大数据量查询、报表生成等操作可能需要更长的处理时间。等待时间应该结合业务实际情况设置,避免因为超时过长而掩盖真实问题。

CueCast 如何处理等待和异步加载?

在实际测试中,为每个操作手工设计等待逻辑比较繁琐。为了减少这类配置,零代码自动化测试工具 CueCast 将一部分等待处理集成到了测试回放过程中。

首先,目标暂时没有出现时,会继续尝试定位。

CueCast 在录制时保存目标元素信息,回放时用于重新定位。如果目标暂时没有出现,会在限定窗口内重复查找。对于可识别的 Loading 状态,也会观察加载是否结束。

另外,定位成功后,还会确认元素是否可操作。

对于点击等交互步骤,CueCast 会检查按钮是否被禁用、组件是否仍在 Loading、输入框是否只读,以及目标是否被遮罩挡住等。只有当前目标满足操作条件,才继续执行。如果页面其他区域仍在加载,但当前目标已经可以操作,也无需一直等待。

这套机制能够适应正常的加载时间波动。例如同一个按钮有时 1 秒出现,有时需要 5 秒,只要在等待窗口内满足条件,就可以继续执行。

等待也有明确上限。同一步骤的多次定位共用等待预算,如果目标始终无法出现或操作,就会结束当前步骤并报告失败,避免无限等待。

UI2.png

遇到特殊场景,还可以手动补充等待。

例如展开筛选面板后,短动画可能影响后续输入。这种情况下可以在用例详情中,为对应步骤设置以毫秒为单位的“执行前等待”。这属于固定等待,每次都会等满设定时间,所以更适合局部使用。

UI3.png

通过断言,等待真正的业务结果

元素能够正常操作,只能说明测试顺利执行了当前步骤,并不能保证业务已经完成。

例如,自动化测试点击“保存”按钮后,页面出现了成功提示,但后台可能还在处理数据,新记录也尚未出现在列表中。如果此时立即检查结果,就可能因为数据还没更新而导致测试失败。

因此,对于存在异步处理的业务,除了等待元素可操作,还需要等待预期的业务结果出现。

CueCast 的文本断言支持两种检查方式:

  • 等待断言成立:在限定时间内持续检查预期结果,条件满足即可通过。适合列表刷新、状态更新等需要异步处理的场景。
  • 立即检查:执行到断言步骤时直接检查当前结果,适合要求即时呈现某个状态的场景。

这里还有一个容易忽略的细节:断言通过的前提,是选择了正确的验证目标。

假设删除一条记录后,立即检查“列表中不存在该记录”,此时列表如果尚未加载完成,也可能得到相同结果。因此,应先确认列表加载完成,再检查目标记录是否确实消失。

通过合理设置断言条件和等待方式,既能减少异步更新造成的误判,也能让自动化测试真正验证业务流程是否符合预期。

测试超时后,应该怎么排查?

超时只是执行结果,背后的原因可能完全不同。可能是页面加载太慢、元素无法操作,也可能是定位失效,或者上一步业务操作本身就没有成功。

遇到超时,建议先查看失败步骤、执行截图和日志,确认页面当时处于什么状态。比如,页面是否还在 Loading?是否已经出现错误提示?目标元素究竟是没有出现,还是已经出现却无法点击?

接下来,还要回查前面的操作是否正常完成。如果保存操作本身失败,那么后续再怎么等待新记录出现,也无法让测试通过。

以下是几种常见的失败情况及处理思路:

失败现象可能原因处理建议
页面仍在 Loading 或显示骨架屏数据请求或页面渲染尚未完成检查加载状态,确认目标能否正常出现
按钮已出现,却无法点击按钮禁用、遮罩或动画影响等待可操作状态,必要时局部增加等待
点击完成,但没有预期结果业务处理尚未完成,或操作本身失败检查提交结果,补充或调整业务断言
页面已经报错,却一直找不到目标登录失效、权限不足或业务异常优先解决页面错误和前置条件
页面正常,却始终找不到元素页面结构变化或定位失效修正定位或局部重新录制

对于 CueCast,用例失败后可以结合执行截图、失败步骤和日志查看现场,再决定是修改定位、调整等待,还是检查业务本身。

不要把增加超时时间当成万能解法。如果页面已经报错,或者目标定位错误,等待再久也无法解决问题。

总结

等待和超时问题很难完全避免,但合理的等待策略可以减少大量不必要的失败。核心原则其实很简单:等待明确的状态,设置合理的上限,再通过断言确认业务结果。

无论是写测试脚本,还是用 CueCast 这样的零代码工具,都应该围绕这个原则设计测试流程。减少无意义的固定等待,也能让长期回归测试更稳定、更高效。