自动化测试的历史始于提高速度和减少人为因素的检查,但很快发现自动化测试在每次运行时的行为往往不同。可重复性(repeatability)和确定性(determinism)是自动测试质量的基本要求之一,应该在相同条件下给出相同的结果。
问题源于隐性依赖:不稳定的测试数据、未同步的环境、并行过程或外部服务。这导致了flaky测试——其结果无法预测。
解决方案围绕严格控制执行环境、测试隔离、模拟/存根对象、静态数据和可重现场景构建(例如,在每个测试之前清理和准备数据库)。
关键特性:
如果flaky测试只在CI中出现,而本地一切正常,应该怎么办?
这几乎总是与环境的差异有关:依赖版本、基础设施的运作速度、并行性、OS设置或测试运行顺序。解决方案是尽可能将CI环境逼近开发机器(Docker、相同的种子值、设置setUp/tearDown配置)。
如果参数化测试的数据来自数据库,是否可以认为测试完全确定?
不可以。即使数据基本相同,数据库在测试之间或版本之间可以发生变化。为了实现真正的确定性,数据必须在每个测试中显式准备和清理。
如果使用sleep来等待元素加载,是否能解决UI测试的不稳定性问题?
不可以。Sleep仅仅掩盖问题并减慢测试运行。应该正确使用显式等待(Explicit Waits),它们等待特定条件,而不是固定时间。
在项目中,在一个没有在手动测试后清理的环境中运行UI测试。每隔几晚,测试都会因为“随机”错误失败,而这些错误在本地并不存在。团队在测试中添加了sleep并忽略了flaky问题。
优点:
缺点:
在一个成熟的DevOps工程师出现后,团队实现了重置和初始化测试数据的脚本,添加了mock服务以处理不稳定的集成,并开始在容器中运行测试。flaky测试几乎消失。
优点:
缺点: