摆脱前端测试恶梦:摇摆不定的测试(一)

发表于:2021-7-19 10:07

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:前端小工    来源:掘金

  有一个寓言故事,这些天我经常想起。这则寓言是在我小时候告诉我的。它被称为伊索的 "狼来了的男孩"。它讲述了一个在村子里放羊的男孩。他觉得无聊,就假装有狼在袭击羊群,向村民们求救--但他们失望地发现这是一场虚惊,便不再理睬这个男孩。然后,当狼真的出现,男孩呼救时,村民们认为这又是一场虚惊,没有前来救援,羊群最终被狼吃掉了。
  这个故事的寓意由作者本人作了最好的总结。
  "骗子是不会被相信的,即使他说的是实话"。
  狼袭击了羊群,男孩哭着求救,但经过无数次的谎言,已经没有人相信他了。这个寓意可以适用于测试。伊索的故事是一个很好的寓言,说明了我偶然发现的一个匹配模式:未能提供任何价值的片状测试。

  前端测试为什么这么麻烦?
  我的大部分时间都花在了前端测试上。所以你不应该感到惊讶的是,本文中的代码例子大多来自我在工作中遇到的前端测试。然而,在大多数情况下,它们可以很容易地翻译成其他语言并应用于其他框架。所以,我希望这篇文章对你有用--不管你有什么专长。
  值得回顾的是前端测试的含义。就其本质而言,前端测试是一套用于测试Web应用程序的用户界面的实践,包括其功能。
  从质量保证工程师开始,我知道在发布前从检查表上无休止的手动测试的痛苦。因此,除了确保一个应用程序在连续的更新过程中保持无错误的目标之外,我还努力减轻那些你实际上不需要人做的常规任务所造成的测试工作量。现在,作为一个开发者,我发现这个话题仍然很有意义,特别是当我试图直接帮助用户和同事的时候。而在测试中,有一个问题特别让我们做噩梦。

  片状测试的科学性
  一个不稳定的测试是指每次运行相同的分析时都不能产生相同的结果。构建只是偶尔会失败。一次是通过,另一次是失败,下一次又是通过,没有对构建进行任何修改。
  当我回忆起我的测试噩梦时,有一个案例特别出现在我的脑海中。那是在一个UI测试中。我们建立了一个自定义风格的组合框(即一个带有输入字段的可选择列表)。

  通过这个组合框,你可以搜索一个产品并选择一个或多个结果。很多天,这个测试都很顺利,但在某些时候,事情发生了变化。在我们的持续集成(CI)系统的大约十个构建中的一个,在这个组合框中搜索和选择产品的测试失败了。
  失败的截图显示结果列表没有被过滤,尽管搜索已经成功。

  像这样的故障测试会阻碍持续部署管道,使功能交付比它需要的更慢。此外,一个不稳定的测试是有问题的,因为它不再是确定性的--使它变得无用。毕竟,你不会相信一个人,就像你不会相信一个骗子一样。
  此外,故障测试的修复成本很高,通常需要几个小时甚至几天的时间来调试。尽管端到端测试更容易出现问题,但我在各种测试中都遇到过这种情况:单元测试功能测试、端到端测试,以及两者之间的一切。
  另一个重要的问题是他们给我们开发人员灌输的态度。当我开始从事测试自动化工作时,我经常听到开发人员在回应失败的测试时这样说。
  "啊,那个构建。不要紧,再踢一次就好了。它最终会通过的,在某个时候"。
  这对我来说是一个巨大的红旗。它告诉我,构建中的错误不会被认真对待。有一种假设是,一个不稳定的测试不是一个真正的错误,而 "只是 "不稳定,不需要被照顾,甚至不需要被调试。反正以后测试会再次通过,对吗?不是的!如果这样的提交被合并,在最坏的情况下,我们的产品中会有一个新的不稳定的测试。

  原因
  所以,不稳定的测试是有问题的。我们应该怎么做呢?好吧,如果我们知道问题所在,我们可以设计一个反策略。
  我在日常生活中经常遇到这样的原因。它们可以在测试本身中找到。测试可能写得不太理想,持有错误的假设,或者包含不好的做法。然而,不仅仅是这样。摇摆不定的测试可能是更糟糕的迹象。
  在下面的章节中,我们将讨论我所遇到的最常见的问题。

  1.测试方面的原因
  在一个理想的世界里,你的应用程序的初始状态应该是纯洁的,100%可预测的。在现实中,你永远不知道你在测试中使用的ID是否会一直是相同的。
  让我们检查一下我的两个失败的例子。第一个错误是在我的测试夹具中使用一个ID。
{
   "id": "f1d2554b0ce847cd82f3ac9bd1c0dfca",
   "name": "Variant product",
}

  第二个错误是在UI测试中寻找一个独特的选择器,然后想,"好吧,这个ID看起来很独特。我将使用它"。
<!-- This is a text field I took from a project I worked on -->
<input type="text" id="sw-field--f1d2554b0ce847cd82f3ac9bd1c0dfca" />

  然而,如果我在另一个装置上运行这个测试,或者后来在CI的几个构建中运行,那么这些测试可能会失败。我们的应用程序将重新生成ID,在不同的构建中改变它们。所以,第一个可能的原因是在硬编码的ID中找到的。
  第二个原因可能来自随机(或其他)生成的演示数据。当然,你可能认为这个 "缺陷 "是合理的--毕竟,数据的生成是随机的--但想想调试这个数据。要看清一个错误是在测试本身还是在演示数据中,可能非常困难。
  接下来是我无数次纠结过的测试端原因:有交叉依赖的测试。一些测试可能无法独立运行或以随机顺序运行,这是有问题的。此外,以前的测试可能会干扰到后面的测试。这些情况会通过引入副作用而导致测试的不稳定。
  然而,不要忘记,测试是对假设的挑战。如果你的假设一开始就有缺陷,会发生什么?我经常经历这些,我最喜欢的是关于时间的有缺陷的假设。
  一个例子是使用不准确的等待时间,特别是在UI测试中--例如,通过使用固定的等待时间。下面这句话取自Nightwatch.js的测试。
// Please never do that unless you have a very good reason!
// Waits for 1 second
browser.pause(1000);

  另一个错误的假设与时间本身有关。我曾经发现,一个不稳定的PHPUnit测试只在我们的夜间构建中失败。经过一些调试,我发现昨天和今天的时间转换是罪魁祸首。另一个很好的例子是由于时区而导致的失败。
  错误的假设并不止于此。我们也可能对数据的顺序有错误的假设。想象一下,一个包含多个条目信息的网格或列表,比如一个货币列表。

  我们想处理第一个条目的信息,即 "捷克克朗 "货币。你能确定你的应用程序在每次执行测试时都会把这段数据作为第一条吗?会不会在某些情况下,"欧元 "或其他货币会成为第一个条目?
  不要假设你的数据会按照你需要的顺序出现。类似于硬编码的ID,在不同的构建中,顺序可能会改变,这取决于应用程序的设计。

  2.环境方面的原因
  下一类原因与你的测试之外的一切有关。具体来说,我们谈论的是执行测试的环境,测试之外的CI和docker相关的依赖--所有这些你几乎无法影响的东西,至少在你作为测试员的角色中是这样。
  一个常见的环境方面的原因是资源泄漏。通常情况下,这将是一个应用程序的负载,导致不同的加载时间或意外的行为。大型测试很容易造成泄漏,吃掉大量的内存。另一个常见的问题是缺乏清理。
  依赖关系之间的不兼容尤其让我做噩梦。一个噩梦发生在我使用Nightwatch.js进行UI测试时。Nightwatch.js使用WebDriver,这当然依赖于Chrome。当Chrome冲刺更新时,出现了兼容性的问题。Chrome、WebDriver和Nightwatch.js本身不再一起工作,这导致我们的构建时常失败。
  说到依赖性。值得一提的是任何npm的问题,比如权限丢失或npm停机。我在观察CI的过程中经历了所有这些问题。
  当涉及到环境问题导致的UI测试错误时,请记住,你需要整个应用程序堆栈,以便它们能够运行。涉及的东西越多,出错的可能性就越大。因此,JavaScript测试是网络开发中最难稳定的测试,因为它们涵盖了大量的代码。

  3.产品方面的原因
  最后但同样重要的是,我们真的要小心这第三个领域--一个有实际bug的领域。我说的是产品方面的原因,即松散性。最著名的例子之一是应用程序中的竞赛条件。当这种情况发生时,这个错误需要在产品中修复,而不是在测试中修复在这种情况下,试图修复测试或环境是没有用的。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号