在我使用Selenium进行自动化测试的职业生涯中,我遇到了许多抱怨自动化测试的稳定性和可靠性的人。在大多数情况下,用于实现测试方案的逻辑是现场的,但是设计和可伸缩性是一个值得关注的问题。对于在Selenium测试自动化中航行的任何人来说,这都是常见的现象。
在使用Selenium框架多年后,我意识到“一刀切”的方法不适用于Selenium测试自动化。尽管没有设计和开发可伸缩自动化测试的经验法则,但是在使用Selenium框架编写测试时必须遵循某些原则。这些原则也可以称为“selenium最佳实践”。
在此博客文章中,我们讨论了Selenium测试自动化的 16个最佳 Selenium 最佳实践,这些最佳实践可能会帮助您开发设计良好且可扩展的测试套件(或测试用例)。
随后在博客中讨论的大多数Selenium最佳实践都与用于Selenium测试自动化的编程语言无关。因此,无论您使用Selenium进行自动化测试使用哪种语言,这些Selenium最佳实践仍将有价值。
1.避免调用sleep 众所周知,Web应用程序(或网站)的行为取决于许多外部因素,例如网络速度,设备(或机器)功能,访问位置,后端服务器上的负载等。这些因素使预测加载特定Web元素的实际时间变得非常具有挑战性。此处,在对Web元素执行任何操作之前添加延迟(或超时)将延迟执行,同时允许加载特定Web元素。
使用sleep来(例如,Java中的Thread.sleep ,Python中的time.sleep)实现的延迟将测试线程阻塞指定的秒数。对于单线程应用程序,它将阻塞线程并有效地阻止进程。使用sleep有助于增加所需的延迟,但是延迟的持续时间取决于许多因素。不能保证添加的延迟会一直工作。例如,如果您添加了5秒的延迟,那么指定的web元素甚至在10秒之后也不会加载。
driver = webdriver.Chrome()
driver.get("https://www.lambdatest.com/")
time.sleep(5000)
driver = webdriver.Chrome()
driver.get("https://www.lambdatest.com/")
time.sleep(5000)
在上面显示的代码段(在Python中)中,在加载测试URL之后,添加了5秒的阻塞。如果页面上的Web元素在毫秒内成功加载怎么办?随后的5秒延迟不仅延长了测试周期的持续时间,而且还可能导致UI自动化测试的稳定性问题。
想象一下,如果上面的测试片段必须执行5000次(在不同的web浏览器上),延迟会有多长!
使用sleep方法的潜在替代方法是什么?Selenium提供隐式等待和显式等待,它们比sleep更有效地处理延迟。隐式等待通知浏览器为页面上存在的所有Web元素等待指定的持续时间。如果元素的可用时间比隐式延迟时间快,则执行移至代码执行的下一行。例如,如果为指定的元素添加了10秒的隐式等待,但是该元素在3秒内加载,则脚本不会等待剩余的7秒。
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 1 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 另一方面,显式等待是另一种动态Selenium等待,用于在特定条件下在指定的持续时间内停止脚本执行。WebDriverWait和ExpectedConditions可用于实现基于条件的等待。
在下面显示的代码片段中,我们等待Web元素(链接文本为SITEMAP)出现在页面上。如果web元素不存在,则引发异常。
driver = webdriver.Chrome()
driver.get("https://www.lambdatest.com/")
timeout = 10
try:
element_present = EC.presence_of_element_located((By.LINK_TEXT, 'Sitemap'))
WebDriverWait(driver, timeout).until(element_present)
except TimeoutException:
print("Timed out while waiting for page to load")
driver = webdriver.Chrome()
driver.get("https://www.lambdatest.com/")
timeout = 10
try:
element_present = EC.presence_of_element_located((By.LINK_TEXT, 'Sitemap'))
WebDriverWait(driver, timeout).until(element_present)
except TimeoutException:
print("Timed out while waiting for page to load")
有关隐式和显式等待的更多信息,请参阅官网关于 Selenium Waits: Implicit, Explicit, Fluent, And Sleep
2.适当命名测试用例和测试套件 在团队中工作时,在某些情况下,您的团队成员可能需要增强您已经编写的测试。如果您在几个月后重新访问相同的测试,您可能无法弄清测试的目的,直到您完成了完整的实现。
如果某些测试在执行阶段失败,只需快速查看测试名称就可以很容易地找出哪些功能被破坏了。通过以一种自我解释的方式给出命名测试用例,可以很容易地解决这些问题,这样您和您的队友就不会花费不必要的时间来调查原因。
3.将浏览器缩放级别设置为100%
有时,在Selenium测试自动化过程中,您可能会注意到测试实现在特定的浏览器上无法正常工作。在过时的浏览器(例如Internet Explorer)上执行跨浏览器测试时,通常就是这种情况。
在Internet Explorer上进行浏览器测试是否仍然有意义?
不管使用Selenium进行自动化测试的Web浏览器如何,将浏览器缩放级别设置为100%是Selenium最佳实践之一。此设置具有本机鼠标的感觉,并确保将本机鼠标事件设置为正确的坐标。
与此设置一起,每个区域的保护模式设置(在Internet Explorer中)必须相同,否则您最终可能会收到NoSuchWindowException异常。
4.最大化浏览器窗口 测试人员针对Selenium测试自动化执行的首批操作之一是截取网页的屏幕截图。在测试过程中会截取屏幕截图,以帮助开发人员调试问题并帮助关键利益相关者跟踪产品开发进度。屏幕截图还有助于检测测试失败是由于应用程序失败还是由于Selenium自动化测试所使用的测试脚本中的问题。
默认情况下,Selenium不会以最大化模式打开浏览器窗口。这可能会影响通常附在测试报告中的网页的屏幕快照(或快照)。加载测试URL后立即最大化浏览器窗口,可确保捕获整个网页的屏幕截图。
这是Selenium最佳实践之一,与执行Selenium测试自动化的浏览器无关。如果您想更深入地了解,我们有一个详细的博客,介绍如何使用Selenium WebDriver来获取完整的屏幕截图。
5.选择最适合的Web定位器 Selenium测试自动化的挑战之一是如果与测试代码中使用的定位符相关的实现发生变化,则必须修改自动化测试。 ID, Name, Link text, XPath, CSS Selector, DOM Locator等是Selenium WebDriver中一些常用的Web 定位器。
对于这么多的Web定位器,有必要选择合适的定位器,以最大程度地减少由于用户界面更改而对测试产生的影响。如果存在动态情况,链接文本通常是首选,如果有一个动态的情况。ID、类和名称不仅是最容易使用的,而且比其他web定位器更不脆弱。
在某些情况下,剩下的唯一选择是XPath。XPath引擎可能因浏览器而异。因此,不能保证一个浏览器的XPath将无缝地适用于另一浏览器。诸如Internet Explorer的浏览器没有用于定位Web元素的本机XPath引擎。因此,JavaScript XPath查询引擎通常用于在IE中通过XPath查找元素。这将比本地XPath引擎慢。XPath更脆弱,因为在页面中对元素进行重新排序或引入新的Web元素可能会导致现有的XPath实现失败。如果XPath是唯一的选择,则应该使用Reelative XPath而不是Absolute XPath,有关XPath的更多信息可以在本指南中找到有关在Selenium中使用XPath的信息。
对于测试国际化的应用程序,如果定位标记不包含任何ID或类,则我们可能无法使用LinkText或partialLinkText。对于本地化或国际化测试,应使用部分href,以便即使站点上的语言发生了变化,href链接仍指向相同的位置。
理想的Web选择器顺序为:id > Name > CSSSelector > XPath。 这是StackOverflow上一个有趣的话题,它对流行的Web定位器的性能方面进行了深入的讨论,以使用Selenium进行自动化测试。
6.创建用于跨浏览器测试的浏览器兼容性矩阵 跨浏览器测试是一项艰巨的任务,因为您需要确定在不同浏览器+操作系统组合上进行测试的优先级。如果我们包含浏览器及其浏览器版本,则总数将达到总数。对(浏览器+ OS +设备)组合列表进行形式化非常重要,因为这将有助于确定必须进行跨浏览器测试的组合的优先级。此正式列表也称为“浏览器矩阵”或“浏览器兼容性矩阵”。
浏览器矩阵是从产品分析,地理位置以及其他有关受众使用模式,统计数据计数器和竞争对手分析的详细见解中获得的重要信息。Browser Matrix将帮助涵盖与产品相关的所有相关浏览器,从而减少开发和测试工作。下面是一个示例浏览器兼容性矩阵:
以下位置提供了用于创建浏览器矩阵的模板。 矩阵 7.实施日志记录和报告 如果扩展测试套件中的特定测试失败,则定位失败的测试用例将变得很有挑战性。在诸如测试代码中适当位置的控制台日志这样的情况下,日志可以是一个巨大的救星,有助于更好地理解代码并帮助将问题归零。
一些流行的日志级别(可用流行的编程语言提供)调试,信息,警告,错误和严重。在测试实现中添加不必要的日志可能会导致测试执行延迟。因此,建议在有助于跟踪失败原因的方案中添加级别错误(和/或严重)的日志。
除日志外,报告是Selenium测试自动化的组成部分,因为它有助于确定测试的状态(通过/失败)。在这里,自动化测试报告可以发挥重要作用,因为它有助于跟踪测试套件(或测试用例)的进度以及相应的测试结果。由于提高了测试输出的可读性,报告还有助于最大程度地减少维护测试数据所需的时间。
借助自动化测试报告,可以轻松分析功能并访问测试范围。
没有日志和报告的Selenium测试自动化无法达到使用Selenium框架的唯一目的。这就是为什么日志记录和报告被认为是自动化中最好的Selenium测试实践之一。
8.使用设计模式和原理,即页面对象模型(POM) 在编写Selenium测试自动化脚本时,必须检查其可维护性和可伸缩性。如果网页UI中的更改要求对测试脚本进行最少(或不需要)更改,则可以这样做。假设未适当维护脚本,即使用相同Web元素的不同脚本。在这种情况下,只要web元素发生更改,就必须在测试脚本的多个位置进行相应的更改。
在这里,Page Objects是一种流行的Web UI自动化模式,它可以方便地使用,因为它可以增强测试维护并减少代码重复。页内对象模型(POM),为网页上的控件创建了一个集中式对象存储库。该网页被实现为一个单独的类。因此,每个要测试的网页将具有其对应的页面对象类。
由于Selenium自动化脚本不会直接与页面的Web元素进行交互,因此这简化了代码维护。而是在测试代码和网页上的控件之间放置一个新层(页面类/页面对象)。
除了具有更好的可维护性之外,在Selenium的自动化测试中使用POM有助于减少代码大小,因为可以在多个Selenium测试自动化脚本中重用在不同页面类中定义的页面对象方法。
利用页面对象模型是Selenium的最佳实践之一,可以帮助:
改善测试维护 最小化由于产品UI中的更新而导致的代码更改 增强代码可重用性 简化被测网页的可视化和模型 下面显示的是在Selenium测试自动化项目中使用页面对象的示例目录结构。
我们已经覆盖页对象模型教程使用Java和页面对象模型指南使用C#更早。
9.将BDD Framework与Selenium一起使用 行为驱动开发(俗称BDD)是一种流行的开发方法,有助于以纯英语(称为Gherkin)编写测试用例。这意味着与开发人员和测试人员一起,技术知识最少(或没有)的成员可以参与测试的开发。
BDD框架有助于填补业务人员和技术人员之间的空白,因为他们所有人都有机会进行增强测试的工作。为BDD测试创建的Gherkin文件由功能,步骤和场景以及相关的Gherkin关键字(如Given,When,Then等)组合而成。无论使用哪种BDD框架,使用的功能文件和关键字的格式都是统一的用过的。由于学习曲线非常低,因此可以更轻松地从一个BDD框架转换到另一个BDD框架。
由于业务人员和技术人员在同一页面上,因此测试基于技术和业务建议,因此有助于提高产品质量。与TDD测试相比,BDD测试更有用,因为业务规范或功能规范的更改将在相应的BDD功能和场景中进行最少的更改。与TDD(测试驱动开发)相比,由于使用业务和功能规范创建测试,因此BDD测试具有更长的保存期限。这是最重要的硒最佳实践之一。一些流行的BDD框架包括Cucumber,Behave,SpecFlow等。下面显示的是一个示例功能文件,该文件在DuckDuckGo上搜索LambdaTest:
Feature: LambdaTest search
Scenario: Search for LambdaTest on DuckDuckGo
Given I am on the DuckDuckGo homepage
When I enter search term as LambdaTest
Then Search results for LambdaTest should appear
Feature: LambdaTest search
Scenario: Search for LambdaTest on DuckDuckGo
Given I am on the DuckDuckGo homepage
When I enter search term as LambdaTest
Then Search results for LambdaTest should appear
如果您想进一步了解本节,我们前面已经介绍了使用Gherkin和Behave BDD框架进行业务驱动的开发。
10.遵循统一的目录结构 在使用Selenium框架进行测试时,必须重点关注测试代码的可维护性。一个标准项目可以包含Src和Test文件夹。Src文件夹可以包含子目录,这些子目录包含页面对象,Helper函数和文件,这些文件包含测试方案中使用的Web定位器信息。Test文件夹可以包含实际的测试实现。
对于Selenium测试自动化的目录结构,我们没有标准规则。但是,Selenium最佳实践建议我们使用目录结构,以将测试实现与测试自动化框架分开。这有助于更好地组织测试代码。
11.使用数据驱动测试进行参数化 网站(或Web应用程序)应针对浏览器,设备和操作系统组合(即多个数据集)的不同组合进行测试。在测试自动化脚本中对测试值进行硬编码不是可扩展的解决方案,因为它会导致不必要的膨胀软件和可能的测试代码重复。
更好的解决方案是使用参数化来实现Selenium的数据驱动的自动化测试。参数化有助于针对不同的输入组合(或数据集)执行测试用例。数据集越广泛,测试范围越好。反过来,这有助于提高产品质量和实施良好的selenium测试规范。
我们已经介绍了有关使用Selenium测试自动化进行数据驱动测试的以下主题:
使用TestNG的参数化(对于Java) selenium自动化的JUnit参数化测试 使用PyTest中的固定装置进行数据驱动的测试 12.不要使用单个驱动程序实现 Selenium中的WebDrivers不可互换。在本地计算机上执行自动跨浏览器测试的情况与在连续构建服务器上执行的情况完全不同。在那种环境下,假定下一个测试将使用Firefox WebDriver(或Chrome WebDriver或任何其他WebDriver)将是错误的。
在持续构建环境中执行集成测试时,该测试将仅接收RemoteDriver(即,用于任何目标浏览器的WebDriver)。在所有Selenium最佳实践中,建议使用参数注释来管理不同的浏览器类型,并准备好代码以供同时执行(或并行测试)。小框架可以在使用selenium LabelledParameterized(创建TestNG中@参数和@RunWith JUnit中)。
这种做法将对确保实现足够灵活以使用不同的浏览器类型很有用。
13.提出自主测试用例设计 自动化测试设计仅取决于您计划从测试中实现的目标。当测试套件包含多个测试时,事情可能会变得复杂。Selenium最关键的最佳实践之一是避免测试套件中不同测试之间的相互依赖性,并将测试应该执行的规范与测试执行策略分开。
使用自主测试的另一个主要优点是,您可以探索并行性以加快测试执行速度。如果测试是依赖的,则一个测试的结果也会影响第二个测试。因此,由于它们很大程度上相互连接,因此不能并行执行。如果您仍然无法避免测试之间的依赖关系,并且如果依赖测试失败,则希望跳过测试的执行,则可以使用相关的修饰符和标记(例如@ pytest.mark.incremental装饰器,PyTest中的xfail标记)。
但是,建议尽可能进行自治测试。否则,您可能会错过利用Selenium(和测试框架)为测试执行带来奇迹的机会!
14.在适当的情况下使用断言和验证 使用Selenium进行自动化测试的情况很多,在遇到硬错误时,您可能希望停止测试执行。例如,您使用Selenium自动测试Gmail登录页面,但是用于定位登录框的Web定位器不正确。在这种情况下,应发出断言,因为其余的测试将依赖于登录页面而步履蹒跚。
断言仅在您要在发生严重故障的情况下停止测试执行时才使用(如上述)。如果断言条件为假,执行将停止,并且将不再执行进一步的测试。另一方面,应在错误的严重性较低的地方使用验证,并且无论验证条件的状态如何,您仍要继续执行测试。
您可能会发现JUnit带有示例的断言很有用。
15.避免代码重复(或包装selenium调用) Selenium测试自动化最常见的Selenium最佳实践之一是避免不必要的代码重复。您可能正在使用其他Web定位器(例如XPath,ID等)来访问网页上存在的Web元素。在实现中经常使用的代码应作为单独的API创建,以使代码重复最少。
避免重复也有助于减少代码大小并提高测试代码的可维护性。封装Selenium调用是Selenium最佳实践之一,可以极大地影响维护复杂的测试套件(或测试代码)。
16.利用selenium中的并行测试 Selenium受欢迎的一个主要因素是它对并行测试的支持。几乎所有流行的测试框架(例如PyTest,PyUnit,TestNG,Cucumber等)都提供了在Selenium Grid上并行执行测试的功能。
Selenium中的并行测试使您可以在不同的环境(即浏览器,平台和设备仿真器的组合)上同时执行相同的测试。建议使用Selenium,在实现中启用并行测试,因为它可以大大减少测试执行时间。
开发人员和测试人员可以使用基于云的Selenium Grid(如LambdaTest),使您可以在线对2,000多种真实浏览器和操作系统执行自动浏览器测试。该平台支持所有流行的测试框架。当在高度可扩展且可靠的Selenium网格上执行时,可以进一步利用Grid来提高并行测试的性能。
温馨提示–现在我们已经了解了16个最佳的Selenium最佳实践,现在是时候了,我们还将深入探讨一些最糟糕的Selenium实践,这些实践在使用Selenium执行自动化测试时应该避免!
selenium自动化测试的最差实践 在上面的部分中,我列出了最基本的Selenium最佳实践,以帮助您进行Selenium的自动化测试。现在,我提出一些selenium实践,您应该不惜一切代价避免:
1.文件下载 单击任何提示用户下载文件的链接(或按钮),即可开始在任何Web平台上下载文件。使用Selenium可以自动执行相同的操作,但是缺点是API不会显示有关文件下载的任何进度。因此,您将不会知道是否正在测试下载功能。
此外,下载文件不是测试用户与Web平台交互的必要方面。相反,应该将使用Selenium(和任何必需的cookie)定位的下载链接传递给HTTP请求库,例如libcurl。
- CAPTCHAS CAPTCHA或“完全自动化的公共图灵测试可以告诉计算机和人类分开”是专门设计用来检查人类是否正在执行必要的操作。简而言之,它旨在防止自动化。
在测试环境中禁用CAPTCHAS并添加绕过CAPTCHA的钩子是可用于绕过测试环境中的CAPTCHA检查的两种策略。
3.两方面身份验证(2FA) 两要素身份验证(2FA)是一种安全机制,其中使用Authenticator移动应用生成OTP(一次性密码)。Gmail有一个身份验证器应用程序,该程序将使用随机代码来验证实际的帐户持有人是否尝试登录新系统(或应用程序)。
在Selenium中自动化2FA可能是一个巨大的挑战,并且可能无法保证性能。最好避免在测试环境中自动执行2FA。您还可以选择禁用一组特定用户的2FA(在任何测试系统上)使用其凭据。或者,您也可以配置测试机器,以便对某些IP地址系列(或选定的IP地址)禁用2FA。
4.链接抓取(或抓取) Web爬网(或爬虫)是使用Web爬网程序执行的,Web爬网程序是用于以系统和自动化的方式浏览Internet的自动化脚本。Selenium并不是为蜘蛛链接设计的,因为它需要启动时间,并且遍历DOM可能需要几秒钟(甚至几分钟)。
由于所需的时间是可变的,因此硒永远不应该用于爬网。而是使用curl命令或诸如BeautifulSoup之类的库来爬网。
5.在Gmail,Facebook和其他相关平台上自动登录 使用自动化(带有Selenium或其他测试框架)登录Gmail,Facebook或任何此类网站是违反其政策的。其次,测试可能非常不可靠。
相反,开发人员可以使用相应网站提供的第三方API,因为它更可靠,更不受更改且使用更安全。应避免不惜一切代价将Selenium自动化用于登录目的(在这些网站上)。
6.避免测试依赖性 并行性是跨浏览器测试(和Selenium自动化测试)不可或缺的一部分,因为它有助于加快测试执行速度。但是,不能保证执行顺序。
应完全避免开发相互依赖的测试,因为这是一种不好的做法,并且不能保证可靠性。该测试套件可能会通过一次测试执行,而同一测试套件可能会在下一个周期失败。在提出Selenium自动化测试用例(或测试套件)时,应遵循自主测试用例设计的实践。
7.性能测试 Selenium框架旨在用于自动化测试。不建议使用Selenium和WebDriver进行性能测试,因为它并未针对执行该任务进行优化,因此您可能无法获得预期的结果。
在网站(或Web平台)上,存在许多外部因素,例如浏览器启动速度,HTTP服务器响应的接收速度等,这些都是测试人员无法控制的。与其选择Selenium WebDriver进行性能测试,不如选择专门为性能测试设计的现成工具。
在这篇详细的文章中,我们研究了一些Selenium最佳实践,并选择了一些最差的实践来进行Selenium自动化测试。在提出Selenium测试方案时,您应该永远记住Selenium是自动化测试的理想选择,因此不要将其用于其他类型的测试,因为它可能会读取良好的结果。使用LambdaTest,您可以使用Selenium对2000多种浏览器和操作系统执行自动测试。
如果您遇到其他一些Selenium最佳实践或不良实践,请在评论部分中添加详细信息,我们将在文章后附加相同的内容。