图形用户界面 (GUI) 测试自动化已损坏。回归测试不是测试;它是软件行为的版本控制。我的断言是:不带断言的测试自动化效果更好!
在软件开发和测试自动化中,断言是一种检查计算结果的方法,通常是通过将其与单个预期值进行比较。虽然这非常适合基于单元的测试自动化(即从内部测试系统),但将其应用于测试接口(特别是用户界面)已被证明是有问题的,正如本文将解释的那样。
根据黄金标准方法进行测试、特征描述测试和批准测试的工具数量不断增加,例如 Approval Tests、Jest 或 recheck-web (retest)。这种方法承诺以更少的精力(包括创建和维护)进行更稳健的测试,同时更彻底地进行测试。
本文中的示例可在 GitHub 上找到。
基本的 Selenium 测试
这是一个针对 Web 应用程序登录页面的传统测试的简单示例。使用 Selenium 作为测试框架,代码可能如下所示
public class MySeleniumTest {
RemoteWebDriver driver;
@Before
public void setup() {
driver = new ChromeDriver();
}
@Test
public void login() throws Exception {
driver.get("https://assets.retest.org/demos/app/demo-app.html");
driver.findElement(By.id("username")).sendKeys("Simon");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.id("sign-in")).click();
assertEquals(driver.findElement(By.tagName("h4")).getText(), "Success!");
}
@After
public void tearDown() throws InterruptedException {
driver.quit();
}
}
这是一个非常简单的测试。它打开一个特定的 URL,然后通过其不可见的元素 ID 查找输入字段。它输入用户名和密码,然后单击登录按钮。
按照目前的最佳实践,此测试然后使用单元测试库,通过 assert 语句检查正确的结果。
在本例中,测试确定是否显示文本“Success!”。
您可以多次运行测试以验证成功,但体验失败也很重要。要创建错误,请更改被测网站的 HTML。例如,您可以编辑 CSS 声明
<link href=_"./files/main.css"_ rel=_"stylesheet"_>
更改或删除 URL 的单个字符(例如,将“main”更改为“min”)会将网站更改为显示原始 HTML 而没有布局。

这个小小的更改绝对是一个错误。但是,当执行测试时,它没有显示任何问题,仍然通过。完全忽略如此明显的错误显然不是您对测试的期望。毕竟,它们应该防止您无意中破坏您的网站。
现在,改为更改或删除输入字段的元素 ID。由于这些 ID 是不可见的,因此从用户的角度来看,此更改对网站没有任何影响。但是,当测试执行时,它会失败并显示 NoSuchElementException。这实际上意味着这个不相关的更改破坏了测试。忽略重大更改但在不可见且因此不相关的更改上失败的测试是当前测试自动化中的标准。这基本上与测试应有的行为相反。
现在,采用原始测试并将驱动程序包装在 RecheckDriver 中
driver = new RecheckDriver( new ChromeDriver() );
然后在测试结束时用调用 driver.capTest(); 替换断言,或添加 Junit 5 规则:@ExtendWith(RecheckExtension.class)。如果您从网站中删除 CSS,则测试将失败,这是应该的

但是,如果您更改或删除元素 ID,则测试仍然通过。
这种令人惊讶的能力来自 recheck-web 的“不可破坏”功能,下面将详细解释。这就是测试应该有的行为:检测对用户重要的更改,并且不要因对用户不相关的更改而中断。
工作原理
recheck-web 项目是一个免费的开源工具,它在 Selenium 之上运行。它是基于黄金标准的,这本质上意味着它在第一次执行测试时创建渲染网站的副本,并且测试的后续运行将当前状态与该副本(黄金标准)进行比较。这就是它可以检测到网站以不利方式更改的方式。这也是它如何在元素 ID 更改后仍能识别元素的方式:它只是窥视黄金标准(ID 仍然存在),并在那里找到元素。使用诸如 XPath、HTML 名称和 CSS 类之类的其他属性,recheck-web 在更改后的网站上识别元素并将其返回给 Selenium。然后,测试可以像以前一样与元素交互,并报告更改。

黄金标准测试的问题
一般来说,黄金标准测试有两个主要缺点
- 通常难以忽略不相关的更改。许多更改没有问题(例如,日期和时间更改、随机 ID 等)。出于 Git 具有 .gitignore 文件的相同原因,recheck-web 具有 recheck.ignore 文件。其类似 Git 的语法使其易于指定要忽略的差异。
- 通常维护冗余很麻烦。黄金标准通常具有相当大的重叠。通常,相同的更改必须多次批准,从而抵消了快速测试创建期间获得的效率。为此,recheck 配备了自己的 命令行界面 (CLI),可处理此烦人的任务。CLI(和 商业 GUI)允许用户轻松地将相同的更改应用于所有实例中的相同元素,或者只是立即应用或忽略所有更改。
上面的示例说明了这两个缺点及其各自的解决方案:检测到更改的 ID,但未报告,因为 recheck.ignore 文件中的 ID 属性被指定为使用 attribute=id 忽略。删除该规则会使测试失败,但不会中断(测试仍然执行并报告更改的 ID)。
示例测试使用隐式检查机制,该机制在每次操作后自动检查结果。(请注意,如果您希望执行显式检查(例如,通过调用 re.check),这是完全可能的。)打开 URL、输入用户名和输入密码是在同一页面上执行的三个操作,因此为同一页面创建了三个黄金标准。因此,更改的 ID 被报告了三次。所有三个实例都可以通过在命令行上对 recheck commit --all tests.report 的单个调用来处理。应用更改会使 recheck-web 测试失败,因为 ID 已从黄金标准中删除。这需要 recheck-web 的另一个巧妙功能:retestId。
虚拟常量 ID
retestId 的基本思想是在网站副本中引入一个附加属性。由于此属性仅存在于网站副本中,而不是在实时站点上,因此它永远不会受到更改的影响(除非元素被完全删除)。这称为虚拟常量 ID。
现在,可以在测试中引用此 retestId。只需将对 By._id_("username") 的调用替换为 By._retestId_("username"),此问题即可彻底解决。这也解决了元素难以引用的情况,因为它们最初没有 ID。
过滤器机制
如果没有 .gitignore 文件,Git 会是什么样?过滤掉不相关的更改是版本控制系统最重要的功能之一。传统的基于断言的测试忽略了超过 99% 的更改。相反,类似于没有 .gitignore 文件的 Git,recheck-web 报告所有更改。
是否忽略不感兴趣的更改取决于用户。Recheck-web 可用于跨浏览器测试、跨设备测试、深度视觉回归测试和功能回归测试,具体取决于您忽略或不忽略的内容。
过滤机制就像 .gitignore 文件一样简单(基于 .gitignore 文件),但功能强大。单个属性可以全局或针对某些元素进行过滤。单个元素,甚至页面的整个部分都可以忽略。如果这还不够强大,您可以在 JavaScript 中实现过滤器规则,例如,忽略具有相同基本 URL 的不同 URL 或小于五个像素的位置差异。
理解这一点的良好起点是 预定义的过滤器文件,这些文件与 recheck-web 一起分发。忽略元素定位通常是一个好主意。如果您想了解有关如何维护 recheck.ignore 文件或创建自己的过滤器的更多信息,请参阅文档。
总结
Recheck-web 是少数可用的基于黄金标准测试的工具之一;替代方案包括 Approval Tests 和 Jest。
Recheck-web 提供了快速轻松地创建比传统测试更完整和更健壮的测试的能力。因为它将渲染的网站(或其部分)彼此进行比较,所以可以实现跨浏览器测试、跨平台测试和其他测试场景。此外,这种测试是一种“赋能”技术,它将使人工智能能够生成更多测试。
Recheck-web 是免费且开源的,所以请试用一下。公司的商业模式是提供额外的服务(例如,存储黄金标准和报告以及用于生成测试的 AI),并在 CLI 之上拥有一个商业 GUI,用于维护黄金标准。
评论已关闭。