不跨所有目标浏览器运行所有测试
这个规则的主要思想是,在所有目标浏览器上运行所有测试是多余和不必要的。我们需要清楚地了解通过在不同的浏览器上运行我们的测试将要实现什么。此操作的主要目的是执行浏览器兼容性,以验证应用程序在所有受支持的浏览器上都能正确工作。
但我们真的应该在所有浏览器上运行所有测试来验证这一点吗?当然不是。浏览器兼容性测试可以由一个有限的测试套件来执行,该测试套件具有与所有web元素交互的测试,并且至少执行一次所有的主工作流。
现在让我们看一个例子,它肯定能帮助你理解主要思想。假设我们需要验证需要支持的三个浏览器(Firefox、IE、Chrome)的搜索功能,以及不同的搜索词组合(假设有100个词)。
在这种情况下你会怎么做?您是否要为每个浏览器运行所有100个组合?不,这听起来不明智……让我们从浏览器兼容性开始。我们所需要的是确保搜索输入、搜索按钮和搜索结果列表元素在所有3种浏览器中都能正常工作。我们应该运行搜索100次来验证它吗?当然不是!只需一次就足以验证元素在不同目标浏览器下的行为。
所有其他99个组合只是为了验证搜索的相关性。它们与浏览器兼容性测试本身无关,因此只需使用一个浏览器即可完成。99个测试在一个浏览器而不是三个浏览器?我们节省了将近一个小时的测试套件执行时间。
06
将测试从测试自动化框架中分离出来
要使您的框架具有可维护性,您需要关心它的结构。所谓结构,我指的是组织代码的方式。基本原则很简单——您应该清楚地将测试从测试自动化框架功能中分离出来。换句话说,测试部分中的每个类应该代表一个测试场景,而这些类的每个功能应该是一个测试。
假设我们有一个项目,所有的UI自动化测试都应该测试一个web应用程序。那么你可能想要遵循这种分离的方法:
当您的系统由几个相互连接的UI应用程序组成时,您可能会遇到另一种情况。在这种情况下,最好使用您的测试自动化框架创建一个单独的模块,它将在单独的测试模块之间共享(针对每个应用程序)。
07
使您的测试自动化框架可移植
我见过许多自动化框架,它们需要付出巨大的努力才能在另一台机器上运行,这与用于创建框架的框架不同。这是一个非常糟糕的实践,因为它不允许新工程师或其他团队成员运行测试,而不需要解决安装问题。如果需要在CI服务器上运行测试,该怎么办?如果您的UI测试自动化框架是不可移植的,那么这将是一个非常棘手的任务。这就是为什么我们有一些建议可以帮助你避免这些问题。
首先,不要在本地机器上存储测试自动化文件!如果您有测试执行所需的测试自动化文件,那么应该将它们附加到框架上。如果它们相对较小,您可以将它们与框架本身一起存储在控制版本中。如果它们很大,那么您可以使用外部存储,如Amazon S3或任何其他云存储。然后,实现一种机制,在第一次测试执行期间将这些文件下载到正确的位置(如果文件还不存在的话)。
同样的原则也适用于web驱动程序。出于某种原因,从一个项目到另一个项目,我仍然看到很多需要安装web驱动程序才能运行测试的情况。此外,有时您需要一个特定的web驱动程序版本,如果文档不是很好,您可以花很多时间来查看第一个绿色测试。应该如何应对?
有一个很好的辅助工具叫WebDriverManger。它负责整个驱动程序的下载和配置工作流程。您所需要做的就是在您的框架中再配置一个额外的java依赖项,所有的web驱动程序都将被自动下载和配置!一旦您决定在另一台没有安装任何web驱动程序的机器上运行测试,就不需要人工交互了,这是一个奇迹。
安装WebDriverManager非常简单,在这个页面上有几个简单的步骤。然而,当我第一次为Serenity框架做这件事时,我发现它并不那么简单。
Serenity有自己的web驱动程序配置工作流。我在网上找不到合适的解决方案,所以如果你也决定使用Serenity框架,这一节可能会很有用。该解决方案的主要思想是Serenity具有自定义web驱动程序的机制。你需要做的就是创建一个单独的类来扩展Serenity框架的DriverSource类,并使用WebDriverManager来创建所需的驱动程序:
之后,你只需要在serenity.conf文件中指定几行配置:
通过使用此配置,您不再需要关心web驱动程序配置。所有的东西都会自动安装,这样你就可以为其他工程师节省很多时间。
08
明智地为你的测试命名
测试名称应该非常清楚,并提供一个关于使用此测试测试哪些功能的自描述概念。为什么?首先,您需要在编写测试一年后立即了解每个测试验证的内容。除此之外,您应该始终帮助您的团队成员,并让他们清楚地了解您的所有测试。此外,如果在测试执行过程中有些测试失败了,您应该通过快速查看测试名称来了解哪些功能被破坏了。您不应该浪费时间来验证测试的实际功能。
这是一个糟糕的测试名的例子:
它是糟糕的,因为它没有告诉测试场景的任何细节。这是一个命名良好的测试的例子:
这个测试名要好得多,因为在测试失败的情况下,您可以立即了解哪些功能失败了,而不需要进入测试并验证哪些功能实际上失败了。这只是一个习惯的问题,但许多工程师更喜欢使用“_”分离方法,而不是大小写方式:
09
如果需要在同一页面上列出相关检查,请使用软断言
如果断言失败,则断言的设计方式会使测试失败。最初,断言是为单元测试设计的。这是一个很好的实践,因为每个单元测试应该只做一个特定的断言。
但是在UI自动化中,您可能想要在一行中验证几件事情。假设您有几个要验证的UI元素,其中两个具有一些未预料到的值。对于经典的断言,在测试执行之后,您只会注意到一个错误,然后测试就会失败。这意味着你的测试做得很好!它抓住了一个错误!但是,第二个问题呢?你怎样才能抓住另一个问题呢?是的,只有在第一个问题解决之后。这可能需要几天甚至几周的时间。这就是为什么我们要立即抓住所有的问题!在这里,您可以通过使用软断言机制获得巨大的好处。
这就是为什么记住软断言是有用的。当您需要断言一个条件但又要让测试继续时,就会使用这种类型的断言。通过使用软断言,即使其中一个断言失败,测试执行流也将继续。最后,它将总结失败的断言列表,并让您了解所有发现的问题。
实现软断言的方法有很多。我更喜欢通过一个名为AssertJ的强大断言框架来使用软断言。如果您从未听说过它,那么您一定要阅读我的另一篇文章,该文章展示了使用第三方断言框架可以获得的好处。
https://www.blazemeter.com/blog/hamcrest-vs-assertj-assertion-frameworks-which-one-should-you-choose?utm_source=blog&utm_medium=BM_blog&utm_campaign=top-15-ui-test-automation-best-practices-you-should-follow
下面是一个基于我们测试的软断言的例子:
与往常一样,您可以在下面路径找到例子:
“/src/main/java/pageobject/steps/BaseSteps.java”
10
截屏进行故障调查
这一最佳实践将帮助您在调查测试失败的原因时节省大量时间。您可以实现一种机制,在测试失败时生成一个浏览器屏幕截图。如果您还没有这个机制,或者您刚刚开始创建您的UI测试自动化框架,请记住这个重要的技巧。
根据您使用或不使用的工具,失败步骤的屏幕快照创建的实现可能会有所不同。至于我,我更喜欢使用awesome Serenity框架,它内置了创建截图的机制。此外,它允许您免费保存所有测试步骤的屏幕截图,因为它是内置的框架功能,所以您甚至不需要关心它的实现。
当你使用这个框架来处理你的测试执行时,这是Serenity提供的报告的一小部分:
对于每个相应的步骤,您可以看到相关的屏幕截图,它显示了测试步骤期间web应用程序的状态。非常方便和有用。
11
简化测试而不是添加注释
测试应该总是清晰且易于阅读。如果你有一种感觉,你需要留下一个注释来理解在这一行做了什么,那么你需要后退一步,重新思考你做错了什么。让我们假设在这个测试中,我们需要等待主页被完全加载。我们可以这样做:
它工作吗?是的!清楚吗?我们留下了评论,所以没有!千万别在考试中这么做。相反,您只需要创建一个函数,将这段代码放入其中,并为该函数提供一个合理的名称。在这之后,在测试中,我们可以将这一行替换为:
不再需要任何注释。尽量简化所有的测试,不要在附近添加任何注释。
12
遵循“绿色测试运行”策略
一方面,这是最简单的原则之一。但另一方面,大多数工程师忽略了这条规则。我们所说的“绿色测试策略”是指,如果某些测试失败并且是红色的,那么在您的测试应用程序中100%存在问题。
有时,在某些情况下,应用程序已经有了一个优先级较低的bug列表,而团队在可预见的将来不会修复这些问题。在这种情况下,大多数测试自动化工程师只是忽略了这些测试。它们将它们留在运行中,并在测试执行结束时以许多红色测试结束。一旦测试执行完成,他们就会检查失败的测试,并验证所有的红色测试都是那些由于这些现有的错误或是否有一些新的问题而可能失败的测试。
不,再一次不!根据最佳实践,这不是正确的方法。首先,每次执行结束时,您都不知道是否有一些意外的问题。如果结果是红色的,并且仍然是红色的,那么执行运行状态不会告诉您任何信息。其次,要理解您是否真的有一些意外的错误,或者所有这些错误都是预料之中的,您需要花费一些时间。只要一次就好了。但是测试结果验证是一个重复的过程,您可能每天都要做。一次又一次地做同样的不必要的检查会浪费你大量的时间和精力。
相反,如果您在您的运行中失败了预期会失败的测试,那么您能做的最好的事情就是将它们分离到一个单独的运行中,并在主测试执行中忽略它们。这将为您在研究失败的构建时节省大量时间。当您从构建中分离出所有预期的失败时,您知道如果测试执行导致至少一个红色失败测试,那么它就是一个真正的新问题。在其他任何情况下,它们都应该是绿色的。
13
使用数据驱动而不是重复测试
当您需要使用不同的数据来测试相同的工作流时,数据驱动测试非常有用。假设您希望验证不同城市之间的航班搜索。没有数据驱动的测试是这样的:
但是如果您需要测试10个或100个组合呢?我们的测试文件将快速增长,变得不方便使用和不可维护。主要是因为如果我们需要对工作流本身做一个小的更改,那么我们需要对所有的测试应用相同的更改!这就是数据驱动测试可以给您带来巨大好处的地方。通过使用数据驱动测试,您只能使用一个测试和一个数据数组,我们将使用它来运行所有不同的数据组合:
看起来干净?现在只需要维护一个。如果您想用一个额外的组合再编写一个测试,您所需要做的就是将这个额外的组合添加到测试数据数组中。
你可在下面路径找到例子:
“/src/test/java/ui/pageobject/DataDrivenExampleTest.java”
14
所有的测试都应该是独立的
你可能不同意,但我坚信所有的测试都应该是独立的。依赖关系将使您的测试难于阅读和维护。在并行自动化运行期间,您肯定会遇到麻烦,因为在并行测试期间,您不能保证运行中测试的顺序。如果您需要实现一个对许多测试都有效的前置条件,那么只需使用“Before”方法,并将其配置为在测试执行期间只运行一次。
15
建立详细的自动化测试报告
测试自动化报告对于优化QA自动化工程师的工作非常重要。理想情况下,您不应该花费超过10- 20%的时间来验证不同测试执行的测试结果。
关于如何进行这一步,有很多选择。您可以通过使用基本的测试执行工具(如TestNG)来设置报告(本文将对此进行介绍)。您可以与测试管理工具(如Zephyr、X-Ray或TestRail)进行集成。或者,您可以使用提供这些功能的高级框架。
在我的自动化框架中,我喜欢使用Serenity框架,它为您提供出色的实时测试报告,显示根据执行结果、类型、标记、功能等分组的所有测试。除此之外,它还为每个测试提供了非常详细的步骤说明,这在结果分析期间非常有用。我强烈推荐使用我们的测试自动化框架,它是使用Serenity框架开发的。现在,您自己尝试一下报告。你所需要做的就是通过在项目根的命令行中运行指定的命令来执行所有的测试:
之后,结果报告文件将通过以下路径定位:“/target/site/serenity/index.html”。
结论
UI测试自动化不是不稳定的。你的UI测试自动化框架的稳定性只取决于你自己。真实、稳定和可靠的UI自动化是一项艰苦的工作,但它也很有趣。在您的框架创建之初,您有一个选择:是使用一个能够帮助您实现目标并解决问题的工具,还是创建一个您将在日常工作中反复使用的软件?对我来说,答案很清楚。