基于 SELENIUM 的自动化测试架构
非常感谢各位查阅本篇文章,笔者在此感谢各位。
目前市面上有分门别类的自动化测试工具,这篇文章将讨论开源自动化测试工具 Selenium
的使用,以及围绕该工具进行自动化测试的理念、方案以及测试架构的构建。
1. 工具的使用
1.1 Selenium 介绍
Selenium
是开源的自动化测试工具,它主要是用于Web 应用程序的自动化测试,不只局限于此,同时支持所有基于web 的管理任务自动化。
Selenium
官网的介绍如下:
Selenium is a suite of tools to automate web browsers across many platforms.
- runs in many browsers and operatingsystems
- can be controlled by many programming languages and testing frameworks.
Selenium 是用于测试 Web 应用程序用户界面 (UI) 的常用框架。它是一款用于运行端到端功能测试的超强工具。您可以使用多个编程语言编写测试,并且 Selenium 能够在一个或多个浏览器中执行这些测试。
Selenium 经历了三个版本:Selenium 1,Selenium 2 和 Selenium 3。Selenium 也不是简单一个工具,而是由几个工具组成,每个工具都有其特点和应用场景。
Selenium 诞生于 2004 年,当在 ThoughtWorks 工作的 Jason Huggins 在测试一个内部应用时。作为一个聪明的家伙,他意识到相对于每次改动都需要手工进行测试,他的时间应该用得更有价值。他开发了一个可以驱动页面进行交互的 Javascript 库,能让多浏览器自动返回测试结果。那个库最终变成了 Selenium 的核心,它是 Selenium RC(远程控制)和 Selenium IDE 所有功能的基础。Selenium RC 是开拓性的,因为没有其他产品能让你使用自己喜欢的语言来控制浏览器。这就是 Selenium 1。
然而,由于它使用了基于 Javascript 的自动化引擎,而浏览器对 Javascript 又有很多安全限制,有些事情就难以实现。更糟糕的是,网站应用正变得越来越强大,它们使用了新浏览器提供的各种特性,都使得这些限制让人痛苦不堪。
在 2006 年,一名 Google 的工程师, Simon Stewart 开始基于这个项目进行开发,这个项目被命名为 WebDriver。此时,Google 早已是 Selenium 的重度用户,但是测试工程师们不得不绕过它的限制进行工具。Simon 需要一款能通过浏览器和操作系统的本地方法直接和浏览器进行通话的测试工具,来解决Javascript 环境沙箱的问题。WebDriver 项目的目标就是要解决 Selenium 的痛点。
到了 2008 年,Selenium 和 WebDriver 两个项目合并。Selenium 有着丰富的社区和商业支持,但 WebDriver 显然代表着未来的趋势。两者的合并为所有用户提供了一组通用功能,并且借鉴了一些测试自动化领域最闪光的思想。这就是 Selenium 2。
2016 年,Selenium 3 诞生。移除了不再使用的 Selenium 1 中的 Selenium RC,并且官方重写了所有的浏览器驱动。
1.2 Selenium 工具集
Selenium IDE
Selenium IDE (集成开发环境) 是一个创建测试脚本的原型工具。它是一个 Firefox 插件,实现简单的浏览器操作的录制与回放功能,提供创建自动化测试的建议接口。Selenium IDE 有一个记录功能,能记录用户的操作,并且能选择多种语言把它们导出到一个可重用的脚本中用于后续执行。
Selenium RC
Selenium RC 是selenium 家族的核心工具,Selenium RC 支持多种不同的语言编写自动化测试脚本,通过selenium RC 的服务器作为代理服务器去访问应用从而达到测试的目的。
selenium RC 使用分Client Libraries 和Selenium Server。
- Client Libraries 库主要主要用于编写测试脚本,用来控制selenium Server 的库。
- Selenium Server 负责控制浏览器行为,总的来说,Selenium Server 主要包括3 个部分:Launcher、Http Proxy、Core。
Selenium Grid
Selenium Grid 使得 Selenium RC 解决方案能提升针对大型的测试套件或者哪些需要运行在多环境的测试套件的处理能力。Selenium Grid 能让你并行的运行你的测试,也就是说,不同的测试可以同时跑在不同的远程机器上。这样做有两个有事,首先,如果你有一个大型的测试套件,或者一个跑的很慢的测试套件,你可以使用 Selenium Grid 将你的测试套件划分成几份同时在几个不同的机器上运行,这样能显著的提升它的性能。同时,如果你必须在多环境中运行你的测试套件,你可以获得多个远程机器的支持,它们将同时运行你的测试套件。在每种情况下,Selenium Grid 都能通过并行处理显著地缩短你的测试套件的处理时间。
Selenium WebDriver
WebDriver 是 Selenium 2 主推的工具,事实上WebDriver是Selenium RC的替代品,因为Selenium需要保留向下兼容性的原因,在 Selenium 2 中, Selenium RC才没有被彻底的抛弃,如果使用Selenium开发一个新的自动化测试项目,那么我们强烈推荐使用Selenium2 的 WebDriver进行编码。另外, 在Selenium 3 中,Selenium RC 被移除了。
1.3 Selenium WebDriver 的使用
接下来的内容,我们将会主要讨论本文的核心重点, Selenium WebDriver 的使用。 Selenium WebDriver 是从 Selenium 2 开始使用并流行, 在 Selenium 3 中得到进一步发展的工具,是当前 Selenium 的最核心的工具。WebDriver 具有清晰面向对象 API,能以最佳的方式与浏览器进行交互。
Selenium WebDriver 就好比是一个懂浏览器的司机,它可以在浏览器的网页上行走,走到网页内容的任何地方,可以参观网页的任何地方,并且和网页进行交互。那么作为测试工程师,如果想和这样的一个司机打交道,就必须要掌握和这样的司机打交道的技能。
- 学习司机会使用的语言,并使用该语言,以及合适的沟通工具与司机进行交流
- Java
- Python
- C#
- JavaScript
- PHP
- Ruby
- 给司机找到合适的浏览器,以便司机在浏览器上行走。
- 支持多种浏览器,包括 Chrome,Firefox,IE,Edge,Safari,Opera 等
Selenium WebDriver 的使用主要分为两个场景:
- 懂浏览器的司机,WebDriver 类
- 用 WebDriver 提供的模板,制造一个司机。
- WebDriver 的第一个应用场景,就是这个司机的各种能力,包括但不限于以下的部分
- 用浏览器打开指定的 URL
- 清理浏览器的Cookie
- 在浏览器中寻找页面元素(Web Element)
- 查找单个的指定元素
- 查找一组有共同属性的元素,并进行遍历等。
- 控制浏览器的基本操作:
- 前进: forward()
- 后退: backward()
- 刷新: refresh()
- 关闭: close()
- 最大化: maximize_window()
- 弹窗: switch_to_alert()
- 返回浏览器的属性
- current_url
- title
- 执行 JavaScript 脚本
- 在浏览器中找到的元素,WebElement 类
- 司机在浏览器中找到页面元素以后,对它做的任何操作,都是 WebDriver 的第二个主要的场景
- 点击该元素: click()
- 清除该元素原有的文字: clear()
- 给该元素填写新的文字: send_keys()
- 获取该元素的文字: text
- 获取该元素的指定属性: get_attribute()
- 对该元素进行二次加工
- 构成 frame 并切换进去: switch_to.frame(元素)
- 构成 select 并进行操作: Select(元素).select_by_value()
- 司机在浏览器中找到页面元素以后,对它做的任何操作,都是 WebDriver 的第二个主要的场景
1.4 Selenium 环境搭建
Selenium 的环境搭建基本上分为三个部分:
- 安装编程语言以及IDE(集成编程环境),用来操作 WebDriver
- 安装 Selenium WebDriver,实现浏览器的测试
- 安装浏览器,和指定的驱动,完成自动化测试的执行
接下来分别用目前市面上主流的 Java 和 Python 环境进行搭建。
Java 版本
安装 Java 语言,即 JDK。推荐 1.8 的版本。
安装 IDE,推荐 JetBrains IDEA Community Edition,这款是目前主流的 Java 开发工具,而且社区版是免费使用的,拥有出色的用户交互,以及使用界面,完全能够应对一般的自动化测试的编程。当然如果你更加熟悉Eclipse,也是可以使用的。
安装 Selenium,推荐使用 Maven 直接引入依赖。当自动化测试作为团队共同的解决方案,而不是一个人单独维护的方案的时候,团队需要统一的 Selenium 版本以及共同的 API 操作,Maven 的使用,无疑简化了项目的难度,很好的解决了此类问题。
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.3.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-remote-driver --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-remote-driver</artifactId> <version>3.3.1</version> </dependency>
当然,你也可以直接下载 Selenium Standalone Server,并且手工引用
Jar 包
到项目中。最新版3.3.1的下载地址:3.3.1安装 浏览器和浏览器的驱动。
以上的步骤,便完成了 Java + Selenium 的环境搭建。
Python 版本
安装 Python 语言。
Python 目前并行了两套版本,2.x 和 3.x。如果你之前没有 Python 的使用经验,建议使用 Python 3.x 版本。两套版本互相不兼容,并且 Python 从 3.5(含)开始,不再支持 Windows XP 系统,请注意。
安装 Python IDE,推荐 JetBrains Pycharm Community Edition。
安装 Selenium,推荐使用 pip 的方式直接安装。在命令行下,直接输入:
# 在Selenium 3 发布之前,可以用下面命令直接装selenium # -U = --upgrade 升级安装 # 自动安装最新版 # 目前3.0发布以后,这个命令直接安装 3.3.1 的最新版 pip install -U selenium # 如果要装2.53.6版本 pip install selenium==2.53.6
如果你处于没有外网的情况下,可以采用源码解压安装,前往https://pypi.python.org/pypi/selenium下载最新版的PyPI版本的Selenium,解压后执行:
python setup.py install
安装 浏览器和浏览器的驱动。
以上的步骤,便完成了 Python + Selenium 的环境搭建。
1.5 Selenium 编程
通过前面的介绍,我们知道 Selenium 支持多种语言,并且推荐使用面向对象的方式进行编程。接下来我们将着重介绍如何使用面向对象的方式进行编程。
在面向对象的理念看来,任何的编码,都是由对象而来的,这里也不例外。和之前介绍 WebDriver 时候的描述对应,我们需要用到两种主要的类,并将其实例化。
- WebDriver 类:主要靠直接实例化该类为对象,然后用其对象直接调用该类的方法和属性
- WebElement 类:主要通过 WebDriver 类实例化的对象,通过对页面元素的查找,得到 WebElement 类的对象,然后调用该类的方法和属性。
具体的使用如下,以 Java 语言 和 火狐浏览器为例
// 声明 Web司机,司机是一个火狐类的对象
// 需要用 new 关键字来实例化对象, () 代表构造方法
WebDriver driver = new FirefoxDriver();
// Web司机去打开网站
driver.get("http://demo.ranzhi.org");
// 线程停止 3000 毫秒,使得 Web司机有足够的时间打开网址
Thread.sleep(3000);
// 选择 用户名 密码 并依次输入 demo 和 demo (用户名和密码都是 demo)
weAccount = driver.findElement(By.cssSelector("#account"));
weAccount.clear();
weAccount.sendKeys("demo");
wePassword = driver.findElement(By.cssSelector("#password"));
wePassword.clear();
wePassword.sendKeys("demo");
// 选择 登录 按钮,并点击 click
driver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(5000);
上述代码中,使用了一个 WebDriver 类 的对象,即第3行,声明了该类的对象,并赋值给变量 driver,接着变量 driver 作为 WebDriver 类的对象,使用了多个 WebDriver 类的方法。
- get(url): 第6行,打开网址
- findElement(by, selector): 第12、16、21行都使用了该方法,同时通过对该方法的调用,分别各产生了一个 WebElement类的对象,
weAccount
,wePassword
和最后一个匿名的对象,并通过产生的三个对象,调用 WebElement 类的方法
- clear():清理页面元素中的文字
- sendKeys(text):给页面元素中,输入新的