北京白癜风的最好医院 https://baike.baidu.com/item/%E5%8C%97%E4%BA%AC%E4%B8%AD%E7%A7%91%E7%99%BD%E7%99%9C%E9%A3%8E%E5%8C%BB%E9%99%A2/9728824?fr=aladdinSelenium自动化测试的主要目的是为了取代和加快手动测试的进程。为了显著提高测试执行的速度,我们可以选择使用不同类型的等待、Web定位器(Locator)、浏览器偏好,来优化并提升Selenium测试的基础设施。
下面,我们将主要从速度和性能两个方面,向您介绍SeleniumWeb测试各项优秀实践,以便您能够更好地加快测试并获取测试结果。
加速Selenium测试的优秀实践
随着软件产品的持续更新,维护和升级Selenium测试的过程会变得越来越复杂。不过,无论被测场景如何不同,下面有关Selenium的基本测试步骤都是相似的:
使用本地或远程的SeleniumWebDriver去打开被测的URL。
使用诸如XPath、CssSelector、以及Linktext等恰当的WebSelenium定位器,来定位所需的各种WebElement。
对已定位的WebElement执行各项必要的操作,并测试页面上的断言。
释放WebDriver所使用的资源。
尽管Selenium测试的效率在很大程度上,取决于测试的方法和内部结构,但是我们可以总结出如下加快执行Selenium测试用例的各种优秀实践:
选择合适的Web定位器
Selenium中的Web定位器往往被认为是任何测试场景的基本构建块。为了自动化与任何Web元素的交互,我们首先应该选对可定位WebElement的Web定位器,然后再对相应的元素执行适当的操作。其中,XPath、CSSSelector、Name、LinkText、PartialLinkText、TagName、以及ClassName都是在Selenium中被广泛使用的Web定位器。我们通常可以将其与find_element或find_elements方法一起使用。
那么,究竟哪一款Web定位器在Selenium中能够最快地定位到元素呢?其实,ID才是最快的Web定位器,毕竟SeleniumWebDriver中的ID定位器,对于页面上的每个元素来说都是唯一的。ID定位器可以返回与指定值(或字符串)相匹配的WebElement。如果页面上存在多个具有相同ID的元素,那么document.getElementById()将返回第一个匹配的元素。主流Web浏览器都优化了document.getElementById()方法,因此我们能够以更快的速度,从DOM处提供WebElement。
如果WebElement并没有ID属性,那么请使用NAME属性。而如果WebElement既没有ID、又没有NAME属性,那就应该使用CSS选择器(Selector)的Web定位器。CSS引擎在所有主流浏览器中都是一致的,并且能够通过Selenium中的CSS选择器,来调优它们的性能,以提供更快的元素识别和更少的测试执行时间。因此,您在使用此类特定的Web定位器时,也会鲜少遇到浏览器的兼容性问题。同时,CSS选择器也能适应IE等老旧的浏览器。
此外,与XPath相比,CSS选择器提供了更好的可读性。我们甚至可以说,XPath是最慢的Web定位器,当您从一个浏览器移至另一个浏览器时,很可能会遇到XPath的一致性问题。因此,仅当您无法在SeleniumWebDriver中选用其他可靠的Web定位器时,才建议使用XPath来定位Web元素。
小结一下,上述Web定位器按照执行速度从快到慢依次是:ID、NAME、CSS选择器、以及XPath。
使用更少的Web定位器
既然您已经确定了最适合加速Selenium测试的Web定位器,下一步就应该将定位器的数量保持在最低限度了。
如前所述,我们每次需要使用find_element(By)或find_elements(By)方法,来定位所需的Web元素,以执行对DOM树的访问。那么对DOM树的访问次数越多,Selenium脚本的执行时间就会越长。因此,如果您以Selenium脚本的最佳执行速度为目标的话,有必要使用更少的Web定位器。这样,我们不但能够提高测试脚本的可读性,还可以最大限度地减少维护脚本所需的时间。
尽量避免Thread.sleep()
现代网站与Web应用往往会使用AJAX(异步的JavaScript和XML)在网页上动态加载内容。因此,页面上的WebElement可能会以不同的时间间隔被加载,这将对尚未处于DOM中的元素造成执行上的困难。
在此,我建议您通过监控document.readyState的状态,来检查DOM状态。document.readyState的完成标志着页面上的所有资源都已加载完毕,因此我们可以开始对页面上存在的WebElement进行相关操作。
由于测试代码中的几秒钟等待,都会增加页面上资源加载所需的延迟,因此我们需要尽量避免使用Thread.sleep(sleep_in_miliseconds)。Selenium中的Thread.sleep()方法将会让代码的执行暂停指定的时间间隔。
复制
/*Pausestestexecutionforspecifiedtimeinmilliseconds*/Thread.sleep();1.2.
如上述代码段所示,我们添加了5秒的等待时间。如果页面元素在指定的持续时间之内(例如2秒钟)就已完成了加载,那么剩下3秒的等待就不必要地增加了测试的执行时间。由于页面的加载时间往往取决于诸如:服务器负载、页面设计、缓存、以及网络带宽等各种外部参数,因此我们无法预测页面的加载时间。可见,无论网页的状态如何,Thread.sleep()方法都会执行固定时间的休眠,因此为了加速Selenium测试,我们需要避免使用它。
重用现有的浏览器实例
目前,能够与Selenium一起使用的所有自动化测试框架,都可以通过提供注释,来加快测试的开发和执行。同时,注释还有助于执行具有不同输入值的测试。当然,只有根据测试的要求,使用正确的注释集,才能加快Selenium测试。
以下是被各个主流自动化测试框架所广泛使用的注释列表:
有时候,您可能需要在相同的浏览器和操作系统类型的组合中,反复运行某个或某组测试。此时,如果您在每个测试的开始时,都创建一个新的SeleniumWebDriver实例,显然会增加测试执行的额外开销。
Selenium的JUnit
下面是Selenium的JUnit中注解的执行顺序:
在使用JUnit框架的Selenium自动化测试中,SeleniumWebDriver实例是在
Before注释下实现的SetUp方法中创建的。已创建的实例是在After注解下实现的TearDown方法中被销毁的。
Selenium的TestNG
下面是Selenium的TestNG中注解的执行顺序:
同理,对于Selenium中的TestNG测试,SetUp方法是在
BeforeMethod注解下实现的,而TearDown方法是在AfterMethod注解下实现的。
在浏览器和操作系统的组合上运行一系列测试
下面,我们来讨论不同的框架在同一个浏览器和操作系统组合上执行三个测试的情况:
(1)JUnit框架
测试-1
Before注解下的setUp()-Test-1-After注解下的tearDown()测试-2Before注解下的setUp()-Test-2-After注解下的tearDown()测试-3Before注解下的setUp()-Test-3-After注解下的tearDown()
(2)TestNG框架
测试-1
BeforeMethod注解下的setUp()-Test-1-AfterMethod注解下的tearDown()测试-2BeforeMethod注解下的setUp()-Test-2-AfterMethod注解下的tearDown()测试-3BeforeMethod注解下的setUp()-Test-3-AfterMethod注解下的tearDown()
如上表所示,在每个测试场景都会在注释之后创建和销毁浏览器实例。
在JUnit和TestNG框架中重用浏览器实例
相反,我们可以使用适当的注释在脚本之间共享相同的浏览器实例:
(1)JUnit框架
测试-1、测试-2和测试-3
BeforeClass注解下的setUp()-Test-1、Test-2和Test-3-AfterClass注解下的tearDown()
(2)TestNG框架
测试-1、测试-2和测试-3
BeforeTest(或BeforeClass)注解下的setUp()-Test-1、Test-2和Test-3-AfterTest(或AfterClass)注解下的tearDown()
在这种情况下,所有测试场景都会使用同一个浏览器实例,并且一旦所有测试执行完成后,该实例就会被销毁。当然,如果测试必须在不同的浏览器和操作系统组合上运行时,则不能使用相同的技术,而必须在每个测试场景之后创建和销毁测试组合。
使用Selenium进行自动化测试的显式等待
Selenium中的隐式等待被应用于测试脚本中的所有Web元素。而隐式等待的主要缺点在于您无法在元素可见、可点击、可选择等条件下执行等待。与此同时,Selenium中的显式等待则允许您对页面上存在的WebElement执行有条件的等待。例如,如果某个被指定的WebElement在显式等待所规定的持续时间内可见,那么就会触发ElementNotVisibleException。如果已定位的元素是可点击的,那么elementToBeClickable方法将返回一个WebElement。
WebDriverWait和ExpectedConditions类的组合可被用于在WebElements上执行显式等待。显式等待的好处在于它是在代码层面,而非远程Selenium部分上运行的。显式等待无需等到设定时间的结束,而是在满足指定条件时,便可立即退出等待。如果设定的条件一旦找到了WebElement,就会将该元素作为结果予以返回。如果WebElement在DOM中并不存在,即使条件中指定时间已过,它也会触发TimeoutException。
在下面的代码段中,我们对visibilityOfElementLocated条件执行了5秒钟的显式等待。如果ID=element的WebElement在5秒内被找到,那么该显式等待就会退出,并返回所需的WebElement。
复制
Java/*Triggeranexplicitwaitof5Seconds*/WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(5));WebElementelement=wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element"))1.2.3.4.
由于只要找到元素就可以访问WebElement,因此实际的等待时间可能会少于设定的等待时间,那么显式等待的测试脚本的性能会更好,也会使得Selenium测试运行得更快。
创建原子性和自主式测试脚本
无论测试场景有多么复杂,我们都需要将复杂的场景分解成为多个“独立和原子性”的测试用例。
像TestNG之类的自动化测试框架能够支持通过诸如dependsOnMethods(用于各种方法)和dependsOnGroups(用于各个组)等注释,来声明测试方法之间的显式依赖关系。但是,只有当您希望在测试方法之间共享数据和状态时,才应该在Selenium测试脚本中使用测试依赖项。
同时,由于原子性测试可被用于故障检测,因此我们需要通过保持测试的简短和原子态,来减少维护测试的工作量。可以说,有了原子性的保证,我们不但可以最大限度地减少测试的依赖性,而且有助于隔离测试中出现的问题,并加快Selenium测试的整体效率。
在Selenium自动化中利用并行测试
Selenium中的并行测试可以让您在不同的测试环境中,同时运行相同的测试。如果您计划使用内部SeleniumGrid进行分布式测试,那么您可以利用SeleniumGrid4所提供的功能,来加速测试场景的执行。
根据所测场景的不同,您可以选择“类”级别或“方法”级别中的任何一种开展并行化测试。而此类测试主要可以对如下三个方面予以增强:
对测试场景分组
测试场景的参数化
选择基于云的SeleniumGrid
对测试场景分组
随着更多的测试文件和测试方法被添加,测试套件的复杂性会成倍增加。为了最大限度地减少测试套件在实现和维护上的复杂性,我们需要根据被测的功能,对测试进行分组。
正如下面对TestNG测试用例进行分组所展示那样,我们创建了两个测试组(即Search和ToDo),并在“方法”级别并行执行。TestNG中的线程计数属性允许您通过指定在测试执行期间要创建的最大线程数,来并行开展测试。
可见,分组测试场景降低了维护测试套件的复杂性,同时也加快了执行时间。当然,这些都取决于为实现并行化而选择的方法。
使用Selenium4(而不是Selenium3)
Selenium4是Selenium自动化框架中最受期待的版本之一。目前,Selenium4的最新版本为4.0.0-beta-1。它在如下方面进行了显著的改进和增强:
改进和优化了SeleniumGrid
对SeleniumWebDriver予以了W3C标准化
增强了Selenium4的IDE
引入了ChromeDevTools
引入了相对定位器(RelativeLocators)
总地说来,Selenium4中的增强功能可以在加速Selenium测试方面发挥重要的作用。
过去,Selenium3使用JSON有线协议,在Web浏览器和测试代码之间进行通信。这会导致使用W3C协议对API请求进行编、解码而产生额外的开销。而Selenium4直接使用WebDriverW3C协议,从而加快了与Web浏览器的通信。这种架构更改不但加快了Selenium测试,而且提高了测试的稳定性。
下图展示的是在Selenium4中新引入的相对定位器。当它在访问临近的特定WebElement时,非常实用。
与页面上的每个WebElement使用find_element()和find_elements()方法不同,相对定位器通过与TagName(在Selenium4的Java中)结合使用,可以让您以更快的速度访问到相对WebElement。因此,在您必须访问相对于DOM元素的WebElement场景时,相对定位器可以加速Selenium测试。
值得一提的是,从Selenium3升级到Selenium4是无缝的,您应当检查版本,以确认是否真的能够利用Selenium4所提供的特性和功能,来加速Selenium测试。
使用基于云的SeleniumGrid进行自动化测试
当涉及到网格的可扩展性和可靠性时,在本地SeleniumGrid上并行运行测试,存在着一个严重的缺陷:它并不适用于在大量浏览器、操作系统和设备的组合上,并行地执行针对大型Web应用的多个测试套件。
所谓云端的Selenium测试,是指在可靠且可扩展的、基于云服务的SeleniumGrid上并行开展测试,因此它有助于加快Selenium测试。由下面显示的testng.xml文件示例可知,该并行是在“测试”级别上实现的。即:每个test标记都在单独的线程中运行。
从下面的执行快照中可以看出,这两个测试都是在基于云端的SeleniumGrid上并行运行的。
使用由基于云端的SeleniumGrid所提供的功能,您可以并行运行“N”个测试(此处的“N”取决于您计划支持的“最大并发会话数”),进而加快Selenium测试。
通过禁用网页上的图像来实现更快的页面加载
一旦创建了SeleniumWebDriver实例,Selenium中的driver.get()方法将被用于打开被测页面。网页的加载速度往往取决于页面的组成。如果页面上有大量的图像的话,那么页面的加载时间就会增加。
因此,通过使用特定于浏览器的设置,您可以按需禁用在相应的Web浏览器中加载图像,以加快网页的加载速度。
运行Selenium脚本时,禁用Chrome中的图像加载
如下代码段展示了如何实现在Chrome中禁用图像的加载,以加快Selenium测试:
复制
Javapackage