精通Selenium WebDriver 3.0 (第2版)(txt+pdf+epub+mobi电子书下载)


发布时间:2021-04-19 12:32:51

点击下载

作者:(印度)马克·柯林(Mark Collin)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

精通Selenium WebDriver 3.0 (第2版)

精通Selenium WebDriver 3.0 (第2版)试读:

前言

本书将着重介绍Selenium高级层面的一些应用。它将帮助你更好地理解Selenium这款测试工具,同时会提供一系列策略来帮助你创建可靠且可扩展的测试框架。

在自动化测试领域,行之有效的实现方式并非只有一种。本书将介绍一系列极简的实现方式,它们非常灵活,可根据你的特定需求进行自定义。

本书不介绍如何编写那些厚重的测试框架,以隐藏Selenium的细节。相反,本书将展示如何通过实用的附加功能来扩展Selenium,这些附加功能可以融入Selenium提供的丰富且精心设计的API中。本书读者对象

如果你是一名软件测试工程师或开发工程师,同时使用过Selenium、了解Java并且对自动化测试感兴趣,还希望提升测试技能,那么本书非常适合你。本书内容

为了让你能够快速入门,第1章先讲解如何建立一个基本的测试框架。之后会重点介绍如何通过Maven来设置项目,以下载依赖项。然后,使用TestNG在同一个浏览器中运行多个实例,展示并行执行测试的优势。接下来,讨论如何使用Maven插件自动下载驱动程序文件,使测试代码变得可移植,以及如何在后台模式下不间断地执行测试。

第2章探讨当测试执行失败时的应对方案。该章会深入分析测试可靠性为何十分重要,如何在Maven配置文件中设置测试的执行方式。你将了解持续集成、持续交付和持续部署的相关概念,并在持续集成服务器中设置测试构建。你还将学习如何连接到Selenium-Grid,如何在测试失败时截屏,以及如何通过读取栈追踪信息来分析测试失败的原因。

对于自动化测试出错的案例,第3章提出大量见解。该章探索Selenium能够产生的各类异常,介绍它们的意义。此外,你会更好地理解WebElement引用DOM元素的原理,了解Selenium的基本体系结构,并了解它如何向浏览器发送命令。

第4章讲述自动化测试失败的常见原因,以及各种等待解决方案。你将学习Selenium中等待策略的运作方式,了解如何使用等待策略来确保测试的稳定性和可靠性。

第5章探讨页面对象的定义,讲解如何有效使用这些对象避免失效。同时,该章还将介绍如何复用页面对象,精简代码以减少冗余,增强自动化测试的可读性。最后,该章展示如何创建流式页面对象。

第6章讲解如何使用高级用户交互API。你将学习如何挑战一些高难度的自动化场景,如悬停菜单和可拖曳控件。同时,该章还将探讨使用高级用户交互API可能遇到的一些问题。

第7章介绍JavascriptExecutor类的用法。该章将探讨如何使用JavaScript来解决复杂的自动化问题,还将讨论如何执行异步脚本,在执行完成时使用回调函数来通知Selenium。

第8章展示Selenium本身的局限性。接下来将探讨在各种场景下如何使用外部库和应用程序来扩展Selenium,以便你可以使用合适的工具和手段来完成任务。

第9章展示如何将Docker和Selenium结合在一起。你会发现在Docker中启动Selenium-Grid是多么容易的一件事,还将了解如何将Docker集成到构建过程中。

第10章首先讲述机器学习和人工智能,然后讨论如何通过Applitools Eyes使用人工智能技术。

附录A讲述有助于改善Selenium项目的各种途径。

附录B探讨从TestNG切换到JUnit所需的转变。

附录C讲述如何创建基于Appium的测试框架。如何充分阅读本书

本书所使用的软件如下:● Oracle JDK8;● Maven 3;● IntelliJ IDEA 2018;● JMeter;● Zed Attack Proxy;● Docker;● Mozilla Firefox;● Google Chrome。

一般情况下,安装的浏览器种类越多越好。如果要完成本书中的所有练习,则至少需要安装Mozilla Firefox和Google Chrome。

IntelliJ IDEA社区版是免费的,要使用其完整功能,需要购买旗舰版。可以根据自己的喜好,使用旧版本的IntelliJ IDEA或者其他IDE。本书的代码都是用IntelliJ IDEA 2018编写的。下载示例代码

你可以用自己的账号从packtpub网站下载本书的示例代码文件。如果你通过其他途径购买本书,可以访问packtpub网站并注册,文件将直接通过电子邮件发送给你。

可以通过以下几个步骤下载代码。(1)在packtpub网站上注册或登录。(2)选择SUPPORT选项卡。(3)单击Code Downloads & Errata按钮。(4)在搜索框中输入图书名称,然后按照屏幕上的说明进行操作。

下载文件后,请确保使用下列工具的最新版本来解压文件:● WinRAR/7-Zip Windows版;● Zipeg/iZip/UnRarX Mac版;● 7-Zip/PeaZip Linux版。

本书所涉及的代码包也在GitHub上进行托管,请访问GitHub官方网站,在搜索栏输入“Mastering Selenium WebDriver 3.0,Second Edition”进行搜索。如果有代码变更,将直接更新到已有的GitHub库中。

我们还提供了额外的代码包,这些代码包源于各式各样的图书和视频。如果你已访问GitHub官方网站并进入了本书的相关页面,只要单击左上角的PacktPublishing链接就可以访问这些图书和视频。本书约定

本书采用了一些版式约定。

代码段的格式如下。public class BasicTest { private ExpectedCondition pageTitleStartsWith(final String searchString) { return driver -> driver.getTitle().toLowerCase(). startsWith(searchString.toLowerCase()); }

命令行的输入/输出会按如下格式书写。mvn clean verify -Dwebdriver.gecko.driver= 表示警告或重要说明。

  表示提醒信息或小提示。联系方式

我们始终欢迎读者的反馈意见。

常规反馈:发送电子邮件至feedback@packtpub.com,邮件标题中请带上书名。如果对于本书有任何疑问,请发电子邮件至questions@packtpub.com。

勘误表:虽然我们已经全力确保内容的正确性,但错误仍旧难以完全避免。如果你在本书中发现任何错误,我们将非常感谢你的反馈。请访问packtpub网站,选择图书名称,单击Errata Submission Form链接,并录入详细信息。

盗版:如果你在网上发现盗版的packt图书,无论它们是以什么形式在互联网上传播的,请把地址或网站名称提供给我们,我们将不胜感激。请通过copyright@packtpub.com与我们联系,并提供相关链接。

投稿:如果你具备相关专业知识,有意愿主导或参与图书撰写,请访问packtpub网站。评论

请不吝点评。在你阅读本书后,为什么不在下单的网站评论一番呢?你的客观意见将为那些正在观望的读者提供参考,帮助他们决定是否购买本书,也可以帮助我们了解你对本书的看法,同时有利于作者了解你对本书的反响。非常感谢!

有关Packt的更多信息,请访问packtpub网站。资源与支持

本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。配套资源

本书配套资源包括源代码。

要获得以上配套资源,请在异步社区本书页面中单击,跳转到下载界面,按提示进行操作即可。注意,为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

如果您是教师,希望获得教学配套资源,请在社区本书页面中直接联系本书的责任编辑。提交勘误

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,单击“提交勘误”,输入勘误信息,单击“提交”按钮即可,如下图所示。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。与我们联系

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您所在的学校、培训机构或企业想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。关于异步社区和异步图书“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。异步社区微信服务号第1章 如何加快测试速度

你或许有所耳闻,Selenium的主要问题之一便是运行完所有测试要花多久的时间。据我所闻,测试时间短则几小时,长则几天。本章将介绍如何提升运行速度,使你写出的测试能快速、定期地运行。

你可能会遇到的另一个问题是其他人如何运行你的测试。问题的原因通常在于,要在其他计算机上配置项目并使其可以运行简直是一种痛苦,对他们来说,这太费劲了。除了要提升测试速度外,还要让其他人很容易获取你的代码并自己运行。

如何通过创建快速反馈循环来做到这一点?

首先,解释一下快速反馈循环的含义。当开发人员更改或重构代码时,他们可能会出现失误,改错某些东西。一旦他们提交了代码,反馈循环就会启动,并在结束时告知这些代码变更是对还是错的。我们希望反馈循环尽可能快,在理想情况下,开发人员在签入代码之前就可以运行所有可用的测试。如此一来,在测试代码之前,就能够知道对代码的修改是否有错。

最终,我们想要达到的目的是找出开发人员做的哪些更新会导致测试失败,毕竟功能发生了变化。这些最终版本的代码会使测试转变为实时文档,第2章将会讨论这方面的更多内容。

本章将从创建一个基本的测试框架开始讲解。需要哪些软件呢?在编写本章代码时,所使用的软件和浏览器版本如下。● Java SDK 8● Maven 3.5.3● Chrome 66● Firefox 60

请确保你的软件至少已更新至上述版本,以确保一切能正常运作。1.1 使开发人员易于运行测试

理想情况下,每当有人向中央代码库推送代码时,我们希望测试能够运行。这样做的一部分原因是可以让测试的运行变得十分容易。如果只签出代码库然后执行命令就可以让所有测试运行起来,这就意味着开发人员更可能运行测试。

我们将使用Apache Maven来简化这个过程。引用Maven文档里的一句说明:“Maven试图将模式应用到项目构建的基础设施中,提供明确的途径来使用最佳实践,以提高理解力和生产力。”

Maven是一种用于构建和管理Java项目的工具(包括下载所需的任何依赖项),在许多公司中都作为标准企业基础设施的一部分。Maven并不是解决这个问题的唯一方法(例如,Gradle是一个非常强大的替代方案,在许多领域它与Maven的功能一样强大,甚至在一些方面超过了它),但Maven是最有可能在周围看到的一个工具。大多数Java开发人员将在其职业生涯的某个阶段使用这个工具。

Maven的一个主要优点是它鼓励开发人员使用标准化的项目结构,使熟悉Maven的人可以轻松浏览源代码。Maven还易于接入CI系统(如Jenkins或TeamCity),因为所有主要的系统都能理解Maven POM文件。

Maven是如何让开发人员轻松运行测试的呢?当我们使用Maven设置项目时,它可以签出测试代码,只需要在终端窗口中键入mvn clean verify,即可自动下载所有的依赖项,设置类的路径,并运行所有的测试。

没有比这更容易的事了。1.2 使用Apache Maven构建测试项目

全面讲解Maven的安装和运行并不属于本书探讨的范围。Apache软件基金会已经提供了一个Maven设置指南,只需要5min便可以完成设置。请访问Maven官方网站,单击左侧菜单中的Users Centre选项,页面跳转后Users Centre会展开,再单击其下的子选项Maven in 5 Minutes。

如果你正在使用的是Debian版的Linux,可以轻松使用如下命令。sudo apt-get install maven

如果你在使用Homebrew运行Mac,则只需要以下代码。brew install maven

一旦完成安装并运行Maven后,就可以使用基本的POM文件来启动Selenium项目了。首先创建一个基本的Maven目录结构,然后在里面新建一个名为pom.xml的文件。查看下方的截图。

在Java环境中,你可能会接触到两种主流测试框架——JUnit 和TestNG。TestNG更易于上手,而且能够开箱即用,但是JUnit 的可扩展性更好。在Selenium的邮件列表中,许多人都在询问关于TestNG 的问题,TestNG 无疑更受大众欢迎,而关于JUnit的问题却不常见。

这里不建议将其中任何一个作为正确之选,因为它们都是业界里极其出色的框架。由于TestNG似乎更受大众欢迎,因此本章重点介绍TestNG的实现方式。

如果你更喜欢JUnit,那么可以参考附录B。在那里将实现相同的基础项目,但使用的是JUnit而不是TestNG。这意味着你可以同时参阅TestNG的实现方式和JUnit的实现方式,而不是纠结用哪个最好。你也可以在之后选择自己喜欢的那个,并阅读相关章节。

首先看一下基于TestNG的Maven项目,它的基础POM代码如下。 com.masteringselenium.demo mastering-selenium-testng DEV-SNAPSHOT 4.0.0 Mastering Selenium TestNG A basic Selenium POM file http://www.epubit.com UTF- 8 UTF- 8 1.8 3.12.0 6.14.3 3.7.0

2.21.0 1 org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version} ${maven-compiler-plugin.version} org.seleniumhq.selenium selenium-java ${selenium.version} test org.seleniumhq.selenium selenium-remote-driver ${selenium.version} test org.testng testng ${testng.version} test

这里看到的主要是Maven模板代码。其中groupId、artifactId和version都遵循如下标准的命名规范。● groupId应当是你拥有或控制的域,通过反向方式输入。● 由于artifactId的名称将会分配给JAR文件,因此请注意将其命名

为需要的JAR文件名。● version应始终是一个数字,其末尾带有“-SNAPSHOT”,这表

明它当前是一个进行中的任务。

这里添加了Maven编译器插件,以便可以指定编译代码所需的Java版本。这里选择的是Java 8,因为这是Selenium目前支持的最低Java版本。

接下来引用代码所依赖的库,它们保存在依赖项区块中。首先为Selenium和TestNG分别添加了一个依赖项。请注意,只给它们指定测试所需的范围,这将确保这些依赖项只加载到测试运行时的类路径中,而绝不会打包在作为构建过程的一部分而生成的任何工件中。 使用Maven属性来设置依赖项版本。这不是必需的,却是一种常见的Maven规范。要点在于,如果它们都在一个地方声明,那么后续更新POM中各项内容的版本会更加容易。XML可能非常冗长,而且要通过POM查找将要更新的各个依赖项或插件的版本非常艰难,要花很长的时间,尤其是在你刚开始使用Maven配置文件时。

现在可以用自己的IDE打开POM文件。(在本书中,假设你使用的是IntelliJ IDEA,不过任何主流的IDE应该都能够打开POM文件并从中创建项目。)

现在我们有了Selenium项目的基础。下一步便是创建一个基本的测试,使其可以通过Maven运行。首先,创建一个src/test/java目录。你的IDE应该能自动将该目录识别为测试源码目录。然后,在该目录中创建一个名为com.masteringselenium的包。最后,在这个包中,创建一个名为BasicTest.java的文件,在这个文件中将编写如下代码。package com.masteringselenium;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.firefox.FirefoxDriver;import org.openqa.selenium.support.ui.ExpectedCondition;import org.openqa.selenium.support.ui.WebDriverWait;import org.testng.annotations.Test;public class BasicTest { private ExpectedCondition pageTitleStartsWith(final String searchString) { return driver -> driver.getTitle().toLowerCase(). startsWith(searchString.toLowerCase()); } private void googleExampleThatSearchesFor(final String searchString) { WebDriver driver = new FirefoxDriver(); driver.get("http://www.baidu.com"); WebElement searchField = driver.findElement(By.name("q")); searchField.clear(); searchField.sendKeys(searchString); System.out.println("Page title is: " + driver.getTitle()); searchField.submit(); WebDriverWait wait = new WebDriverWait(driver, 10, 100); wait.until(pageTitleStartsWith(searchString)); System.out.println("Page title is: " + driver.getTitle()); driver.quit(); } @Test public void googleCheeseExample() { googleExampleThatSearchesFor("Cheese!"); } @Test public void googleMilkExample() { googleExampleThatSearchesFor("Milk!"); }}

相信读者都非常熟悉这两个测试,它们都是基本的Google搜索场景,所有复杂的操作都被抽象到了一个方法中,可以传入不同的搜索关键字来多次调用该方法。万事俱备,只欠运行测试。要启动它们,只需要在终端窗口中输入如下命令。mvn clean verify

Maven会从Maven Central下载所有Java依赖项。这一步完成后,就会构建项目,接着运行测试。 如果你在下载依赖项时遇到问题,请尝试在命令末尾添加-U,这将强制Maven检查Maven中央仓库以获取更新后的库。

接下来将看到Firefox成功启动,不过测试无法正常运行。原因在于Selenium 3中所有的驱动文件都不再默认与Selenium绑定,现在必须单独下载相关的驱动文件才能运行测试。

先下载该文件,然后将一个环境变量传给JVM,以便能顺利运行首个测试。稍后还将介绍一个稍微简化的方法,用来自动下载所需的驱动文件。

由于正在对Firefox运行测试,因此需要下载geckodriver文件。要获取最新版本,可以访问GitHub官方网站,在搜索栏中输入geckodriver进行搜索,在搜索结果中选择mozilla/geckodriver后进入项目页面,然后单击releases选项卡。

既然有了一个可用的驱动文件,就需要告诉Selenium在哪里找到它。幸运的是,Selenium团队已经提供了一种方法。当Selenium启动并尝试实例化驱动对象时,它将查找一个系统属性,该属性用于保存测试所需的可执行文件路径。这些系统属性的格式为WebDriver..driver。为了让测试顺利运转,需要在命令行上传入这个系统属性。mvn clean verify -Dwebdriver.gecko.driver=

这次,Firefox应该能正确加载,顺利运行测试且不带任何错误,最终的测试状态为通过。 如果仍有问题,请检查你正在使用的Firefox版本。本章中的代码是针对Firefox 60编写的。如果你使用的是早期版本,geckodriver可能无法完全支持,也许会遇到一些错误。

现在我们已拥有一个非常基础的项目,可以用Maven来运行几个非常基础的测试。目前来说,一切都运行得非常快,但当你开始向项目中添加更多的测试时,速度就会开始放缓。为了解决该问题,我们将并行执行测试,充分利用计算机的所有性能。1.3 并行执行测试“并行执行测试”对不同的人来说会有不同的理解,因为它可能表示以下任意一种情况。● 同时在多个浏览器上执行所有测试。● 在同一个浏览器的多个实例上执行所有测试。

我们应该把并行执行测试作为提高测试覆盖范围的手段吗?

当然,在你编写自动化测试时,为了确保当前正在测试的网站能够正常运作,最初都会告知你网站必须要支持所有的浏览器。实际上,这是不现实的,浏览器种类太多了,不可能全都支持。例如,对于拥有许多奇异对象的AJAX密集型站点,它难道能在Lynx浏览器上运行吗? Lynx是一个基于文本的Web浏览器,可以在Linux终端窗口中使用,并且在2014年还在积极开发中。

接下来你可能会听到:“好吧,那我们将支持Selenium所支持的每个浏览器。”这些初衷都是好的,但还会遇到麻烦。大多数人没有意识到的是,Selenium核心团队官方支持的浏览器是当前版本的浏览器,以及发布Selenium版本时先前版本的浏览器。实际上,它也可能适用于较旧的浏览器,核心团队会做很多工作来确保他们不会破坏对旧浏览器的支持。然而,如果要在Internet Explorer 6、Internet Explorer 7或Internet Explorer 8上运行一系列测试,这些运行测试的浏览器并未得到官方支持。

我们讨论下一组问题。Internet Explorer仅能在Windows计算机上运行,而且在Windows计算机上同时只能安装一个版本的Internet Explorer。 要在同一台计算机上安装多个版本的Internet Explorer,可以使用一些高科技,不过这样就无法获得准确的测试情况。最好预装并运行多个操作系统,但每个系统只安装某一版本的Internet Explorer。

Safari仅支持OS X计算机,且同时只能安装一个版本。 原来一个旧版本的Safari是支持Windows系统的,但现在Windows系统不再支持该版本,请勿使用该版本。

显而易见,即使我们希望针对Selenium支持的每个浏览器都执行全部测试,也无法在同一台计算机上实现此操作。

目前,人们更倾向于修改测试框架,使其可以接收要运行的浏览器列表。开发人员编写了一些代码,用来检测或指定计算机上可用的浏览器。一旦完成这项工作,他们就能够开始在少数几台计算机上并行执行所有测试,最后得到一个类似于下图的矩阵。

这个办法非常好,但它并没有彻底解决一直存在的难题:总有一两个浏览器无法在本地计算机上运行,因此你永远无法得到完全跨浏览器的测试覆盖率。使用多种不同的驱动程序实例(可能在多个线程中)在不同的浏览器上运行,只略微提高了覆盖率。我们仍然没有实现完全跨浏览器的覆盖率。

这样做也会有一些副作用。不同浏览器的运行速度不尽相同,因为各个浏览器中的JavaScript引擎不一样。在将代码推送到源码库之前,检查代码是否正常工作的过程可能会因此非常缓慢。

最终,这样做只会使我们更难诊断问题。一旦测试失败,要逐个排查是哪一个浏览器出的问题并定位失败的原因。这看上去只占用你1min的时间,但所有这些时间加起来就很多了。

为什么我们不暂且只在某一种浏览器上运行测试呢?让它在一种浏览器上运行得又稳又快,然后再考虑跨浏览器的兼容性。 在开发用的计算机上先选择某一种浏览器来运行测试可能是个好办法。然后可以使用CI服务器来弥补这个不足,将浏览器的覆盖率纳入考虑范围,作为构建流水线的一部分。先为本地计算机挑选一个带有快速JavaScript引擎的浏览器也许同样是一个好办法。1.4 使用TestNG进行并行测试

本章中的TestNG示例使用的TestNG版本为6.14.3,Maven Failsafe插件版本为2.21.0。如果你用的是这些组件更旧的版本,部分功能可能会无法使用。

首先,更改POM文件,添加一个threads属性,该属性用于决定运行测试的并行线程的数量。然后,使用Maven Failsafe插件来配置TestNG。 UTF-8 UTF-8 1.8 3.12.0 6.14.3 3.7.0 2.21.0 1 org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version} ${maven-compiler-plugin.version} org.apache.maven.plugins maven-failsafe-plugin ${maven-failsafe-plugin.version} methods ${threads} integration-test verify  当使用Maven Failsafe插件时,设置为integration- test的goal节点将确保测试在集成测试阶段执行。设置为verify的goal节点将确保Failsafe插件可验证在integration-test阶段执行检查的结果,如果某些内容未通过则无法进行构建。如果没有设置verify的goal节点,则构建不会失败。

TestNG支持开箱即用的并行线程,这里只需要告诉它如何使用这些线程。这就是Maven Failsafe插件发挥作用的地方。我们将使用它为测试配置并行执行的环境。如果你将TestNG作为依赖项,则此配置将应用于TestNG,无须做任何特别的事情。

本例所关注的是parallel和threadCount这两项配置。我们已经将parallel节点设置为methods。这将在项目中搜索有@Test注释的方法,并将它们全部收集到一个巨大的测试池中。然后,Failsafe插件会从这个池中取出测试并运行它们。并发运行的测试数量取决于有多少线程可用。我们将使用threadCount属性来控制线程数。

需要注意的是,该方法不能控制测试运行的先后顺序。

我们配置threadCount来控制并行运行的测试数量,你可能注意到,这里没有指定一个数字。相反,这里使用的是Maven变量${threads},这将获取在properties块中定义的Maven属性threads的值,并将其传递给threadCount。

因为threads是Maven属性,所以可以使用-D开关在命令行上重写它的值。如果不重写它的值,它将使用在POM中设置的值作为默认值。

因此,如果运行以下命令,它将使用在POM文件中的默认值1。mvn clean verify -Dwebdriver.gecko.driver=

然而,如果使用这个命令,它将覆盖存储在POM文件中的值1,并使用值2替代。mvn clean verify -Dthreads=2 -Dwebdriver.gecko.driver=

如你所见,这使我们能够调整用于运行测试的线程的数量,而无须对代码进行任何修改。

我们已经使用Maven和Maven Failsafe插件的强大功能来设置并行运行测试时使用的线程数量,但是还有更多工作要做。

如果你现在运行测试,将会发现,即使我们为代码提供了多个线程,所有的测试也仍然只在一个线程中运行。由于Selenium不具备线程安全,因此还需要编写一些额外代码,以确保各个Selenium实例在其独立的线程中运行,而不会在其他线程中运行。

以前在每个测试中都会创建一个FirefoxDirver实例。我们要将它从测试中提取出来,并将实例化浏览器部分放到其归属类DriverFactory中。然后,添加一个名为DriverBase的类,它将处理线程的封送。

现在,我们要构建的项目具有下图所示结构。

首先,创建DriverFactory类,使用的代码如下。package com.masteringselenium;import org.openqa.selenium.firefox.FirefoxDriver;import org.openqa.selenium.remote.RemoteWebDriver;public class DriverFactory { private RemoteWebDriver webDriver; private final String operatingSystem = System.getProperty("os.name").toUpperCase(); private final String systemArchitecture = System.getProperty("os.arch"); RemoteWebDriver getDriver() { if (null == webDriver) { System.out.println(" "); System.out.println("Current Operating System: " + operatingSystem); System.out.println("Current Architecture: " + systemArchitecture); System.out.println("Current Browser Selection: Firefox"); System.out.println(" "); webDriver = new FirefoxDriver(); } return webDriver; } void quitDriver() { if (null != webDriver) { webDriver.quit(); webDriver = null; } }}

这个类持有对WebDriver对象的引用,并确保每次调用getDriver()时都返回一个有效的WebDriver实例。如果某个实例已经启动,那么它将会获取现有的那个。如果需要的实例还没启动,则会先启动一个。

它还提供了一个quitDriver()方法,用于执行WebDriver对象的quit()方法,并将类中定义的WebDriver对象设置为null。这可以防止与已关闭的WebDriver对象进行交互,从而产生错误。 我们使用的是driver.quit()而不是driver.close()。按照一般经验,不应该使用driver.close()来进行清理。如果在测试期间出现的一些情况导致WebDriver实例提前关闭,则将会抛出错误。WebDriver API中的“关闭并清理”命令是driver.quit()。如果在测试时打开了多个窗口,而你只想关闭其中一些窗口,那么通常使用driver.close()。

接下来,使用如下命令创建DriverBase类。package com.masteringselenium;import org.openqa.selenium.remote.RemoteWebDriver;import org.testng.annotations.AfterMethod;import org.testng.annotations.AfterSuite;import org.testng.annotations.BeforeSuite;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class DriverBase { private static List webDriverThreadPool = Collections.synchronizedList(new ArrayList()); private static ThreadLocal driverThread; @BeforeSuite(alwaysRun = true) public static void instantiateDriverObject() { driverThread = new ThreadLocal() { @Override protected DriverFactory initialValue() { DriverFactory webDriverThread = new DriverFactory(); webDriverThreadPool.add(webDriverThread); return webDriverThread; } }; } public static RemoteWebDriver getDriver() { return driverThread.get().getDriver(); } @AfterMethod(alwaysRun = true) public static void clearCookies() { getDriver().manage().deleteAllCookies(); } @AfterSuite(alwaysRun = true) public static void closeDriverObjects() { for (DriverFactory webDriverThread : webDriverThreadPool) { webDriverThread.quitDriver(); } }}

这是一个微型的类,用于封装一个驱动对象池。可以使用ThreadLocal对象在各个独立的线程中实例化WebDriverThread对象。我们还创建了一个getDriver()方法,该方法使用DriverFactory对象上的getDriver()方法来将各个测试传递给可用的WebDriver实例。

这样做是为了隔离WebDriver的各个实例,以确保测试之间不会交叉污染。当开始并行运行测试时,我们不想看到不同的测试都开始向同一个浏览器窗口发送命令。现在,WebDriver中的每个实例都已安全地锁定在自己的线程中。

因为使用工厂类启动所有的浏览器实例,所以还要确保能正确关闭它们。为此,创建了一个带有@AfterMethod注释的方法,用于在测试运行后销毁驱动程序。如果测试在运行中没有正常触发代码行driver.quit(),则这种清理方式将发挥作用,例如,测试在运行时出错了,导致测试失败并提前结束测试。

注意,@AfterMethod和@BeforeSuite注释有一个参数alwaysRun

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载