Selenium 介绍

1. 什么是 Selenium?

Selenium 是一个强大的基于浏览器的开源自动化测试工具,它通常用来编写 Web 应用的自动化测试。其具有以下特性:
  1. 开源:可以根据需要来增加或者重构工具的某些功能。
  2. 跨平台: Linux、Windows、Mac。
  3. 支持多种编程语言。
  4. 核心功能就是可以在多个浏览器上进行自动化测试。
  5. 目前已经被 google、百度、腾讯等公司广泛使用。

 

2. Selenium 发展历程

Selenium 1.0

2004 年,ThoughtWorks 公司里一个叫做 Jason Huggins 为了减少手工测试的工作,自己写了一套 JavaScript 的库,这套库可以进行页面交互,并且可以重复的在不同浏览器上进行重复的测试操作。

这套库后来变为了 Selenium Core,为 Selenium Remote Control(RC)和 Selenium IDE 提供了坚实的核心基础能力。Selenium 1.x 时期主要使用 Selenium RC(Selenium Remote Control)进来自动化测试。

Selenium 的作用是划时代的,因为他允许你使用多种语言来控制浏览器。

Selenium 1.0 组成

  1. Selenium IDE:Selenium IDE 是嵌入到 Firefox 浏览器中的一个插件,实现简单的浏览器操作的录制与回放功能。
  2. Selenium Remote Control(RC)Selenium 家族的核心部分。Selenium RC 支持多种不同语言编写的自动化测试脚本,通过 Selenium RC 的服务器作为代理服务器去访问应用,从而达到测试的目的。Selenium RC 包含 Selenium Core、Client Libraries 和 Selenium Server 三个部分:
    1. Client Libraries主要用于编写测试脚本,用来控制 Selenium Server 的库。
    2. Selenium Server负责控制浏览器行为。
    3. Selenium Core:是整个测试机制的核心部分,即有 assertion(断言)机制的 test suite runner。它由一些纯 js 代码组成,可以运行在 Windows/Linux 的不同 Browser 上。
  3. Selenium Grid可以并行的在多个测试环境执行测试脚本,实现脚本的并发测试执行,以此缩短大量测试脚本集合的执行时间。

Selenium RC 工作原理

  • Selenium Server 负责控制浏览器行为,总的来说,Selenium Server 主要包括3个部分:Launcher、Http Proxy、Selenium Core。其中 Selenium Core 是被 Selenium Server 注入到浏览器页面中的,它其实就是一堆 Javascript 函数的集合。
  • 自动化测试的过程是:Selenium RC 启动一个 Selenium Server,将操作 web 元素的 API 调用转化为一段段 Javascript,在 Selenium 内核启动浏览器之后注入这段 Javascript 函数(即Selenium Core),通过这些 Javascript 函数,我们才可以实现用程序对浏览器进行操作(Javascript 可以获取并调用页面的任何元素,自如的进行操作)。
  • Client Libraries 是写测试用例时用来控制 Selenium Server 的库。测试用例通过调用 Client Libraries 来编写相关的代码。

Selenium 1.0 工作原理

  1. 测试用例(TestCase)通过 Client Libraries 的接口向 Selenium Server 发送 Http 请求,要求和 Selenium Server 建立连接。
  2. Selenium Server 的 Launch 启动浏览器,把 Selenium Core 加载入浏览器页面中,并将浏览器的代理设置为 Selenium Server 的 Http Proxy 。
  3. 测试用例通过 Client Libraries 的接口向 Selenium Server 发送 Http 请求,Selenium Server 对请求进行解析,然后通过 Http Proxy 发送 JS 命令通知 Selenium Core 执行操作浏览器的动作。
  4. Selenium Core 接收到指令后,执行操作。
  5. 浏览器收到新的页面请求信息,于是发送 Http 请求,请求新的 web 页面。Selenium Server 会接收到所有由它启动的浏览器发动的请求。
  6. Selenium Server 接收到浏览器发送的 Http 请求后,自己重组 Http 请求,获取对应的 web 页面(响应)。
  7. Selenium Server 的 Http Proxy 把接收的 Web 页面返回给浏览器。

Selenium 2(WebDriver)

Selenium RC 的缺点

  • Selenium RC 不能处理本机键盘和鼠标事件。
  • Selenium RC 不能处理弹出框、对话框(基本身份认证、文件上传/下载)事件。
  • Selenium RC 使用 Javascript 注入技术,速度不够理想,稳定性大大依赖于 Selenium 内核对 API 翻译成的 Javascript 质量高低。

同时,Web 应用也越来越强大,特性也越来越多,都对 Selenium 的发展来说带来了不少困难。

2006 年,Google 的工程师 SimonStewart 发起了 WebDriver 的项目;因为长期以来 Google 一直是 Selenium 的重度用户,但却被限制在有限的操作范围内,且 WebDriver 项目的目标就是为了解决 Selenium 的痛处。

 

2008 年(北京奥运会年), Selenium 和 WebDriver 这两个项目进行了合并,Selenium 2.0 出现了,也就是大家常说的 WebDriver 。

Selenium 与 WebDriver 原是属于两个不同的项目,WebDriver 的创建者 Simon Stewart 早在 2009 年 8 月的一份邮件中解释了项目合并的原因:

  • 部分原因是 WebDriver 解决了 Selenium 存在的缺点(例如能够绕过 JavaScript 沙箱,我们有出色的 API)。
  • 部分原因是 Selenium 解决了 WebDriver 存在的问题(例如支持广泛的浏览器)。
  • 部分原因是 Selenium 的主要贡献者和我都觉得合并项目是为用户提供最优秀框架的最佳途径。

一直以来,Selenium RC 是在浏览器中运行 JavaScript 应用,使用浏览器内置的 JavaScript 翻译器来翻译和执行 Selenese 命令(Selenese 是 Selenium 命令集合)。

而 WebDriver 提供了另外一种方式与浏览器进行交互。那就是利用浏览器原生的 API,封装成一套更加面向对象的 Selenium WebDriver API,可以直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类的)。由于使用的是浏览器的原生 API,速度大大提高,而且调用的稳定性交给了浏览器厂商本身,显然是更加科学。同时也避免了 JavaScript 安全模型(绕过 JS 环境的沙盒效应)导致的限制。

然而带来的一些副作用就是,由于不同的浏览器厂商对 Web 元素的操作和呈现存在不同程度的差异,这就要求 Selenium WebDriver 要分浏览器厂商的不同,提供不同的实现。例如 Chrome 有专门的 ChromeDriver,Firefox 有 FirefoxDriver 等等。

除了来自浏览器厂商的支持之外,WebDriver 还可以利用操作系统级的调用,模拟用户输入。

WebDriver 工作原理

  1. 对于每一条 Selenium 脚本,都会创建一个 HTTP 请求并发送给浏览器的驱动。Selenium 首先会确认浏览器的 native component 是否可用而且版本匹配。若匹配则在目标浏览器里启动一整套 Web Service。这套 Web Service 使用了 Selenium 自己设计定义的协议——The WebDriver Wire Protocol。这套协议非常之强大,几乎可以操作浏览器做任何事情,包括打开、关闭、最大化、最小化、元素定位、元素点击、文件上传等等。
  2. 浏览器驱动中包含了一个 HTTP Server(Remote Server),用来接收这些 HTTP 请求。发送请求时,用 WebDriver 的 HttpCommandExecutor 类将命令转换为 URL 作为 Value,命令作为 Key 一起存入 Map 作为 Request,同时会在 Request 的 Body 中存放相应的 By Xpath、id、name。实际发送的 URL 都是相对路径,后缀多以 /session/:sessionId 开头,这也意味着 WebDriver 每次启动浏览器都会分配一个独立的 sessionId,多线程并行的时候彼此之间不会有冲突和干扰。
    • 比如我们要访问某一个网站,则请求地址为 http://localhost:46350/wd/hub/session/sessionId/url,请求 Json 内容为 {"url": "http://www.qq.com"}。
    • 比如我们常用到的 find_element_by_class_name 这个接口,则会转化为 /session/:sessionId/element 这个 URL,然后在发出 Http Request Body 内再附上具体的参数(如 class name 的值)。如要查找一个 classname 为 test 的元素,则请求地址后缀为 /session/sessionId/element,请求 Json 内容为 {"using": "class_name", "value": "test"}。
  3. HTTP Server 接收到请求后根据请求来具体操控对应的浏览器。
  4. 浏览器执行具体的测试步骤。
  5. 浏览器将步骤执行结果返回给 HTTP Server。
  6. HTTP Server 又将结果返回给 Selenium 的脚本,响应内容也是 Json,会返回找到的 element 的各种细节,比如 text、CSS selector、tag name、class name 等等。比如:
{"sessionId": "XXXXX", "status": 0, "state": "success", "value": {"ELEMENT":"2"}, "class": "XXX", "hCode": "XXX"}

JSON Wire protocol

WebDriver 的 JSON Wire 协议是通用的,也就是说不管是 FirefoxDriver 还是 ChromeDriver,启动之后都会在某一个端口启动基于这套协议的 Web Service。例如 ChromeDriver 初始化成功之后,默认会从 http://localhost:46350 开始,而 FirefoxDriver 从 http://localhost:7055 开始。后续我们调用 WebDriver 的任何 API,都需要借助一个 ComandExecutor 发送一个命令,实际上是一个 HTTP Request 给监听端口上的 Web Service。在我们的 HTTP Request 的 Body 中,会以 WebDriver Wire 协议规定的 JSON 格式的字符串来告诉 Selenium 我们希望浏览器接下来做什么事情。

JSON Wire protocol 是在 HTTP 协议基础上,是对 HTTP 请求及响应的 Body 数据的进一步规范。

为什么要基于 HTTP 协议呢?因为 HTTP 协议是一个浏览器和 Web 服务器之间通信的标准协议,而几乎每一种编程语言都提供了丰富的 http libraries,这样就可以方便的处理客户端 Client 和服务器 Server 之间的 Request 及 Response,WebDriver 的结构就是典型的 C/S 结构,WebDriver API 相当于是客户端,而小小的浏览器驱动才是服务器端。

在 WebDriver 中为了给用户以更明确的反馈信息,提供了更细化的 HTTP 响应状态码,比如:

7: NoSuchElement
11:ElementNotVisible
200:Everything OK
……

Body 部分主要传送具体的数据,在 WebDriver 中这些数据都是以 JSON 的形式存在并进行传送的,这就是 JSON Wire protocol。

JSON 是一种数据交换的格式,是对 XML 的升级与替代。下面的例子是 WebDriver 中在成功找到一个元素后 JSON Wire Protocol 的返回:

{"status" : 0, "value" : {"element" : "123422"}}

所以在 Client 和 Server 之间,只要是基于 JSON Wire Protocol 来传递数据,就与具体的脚本语言无关了,这样同一个浏览器的驱动就即可以处理 Java 语言的脚本,也可以处理 Python 语言的脚本了。

需要强调的是,在 Selenium 2.0 中主推的是 WebDriver,可以将其看作 Selenium RC 的替代品(Selenium 为了保持向下的兼容性,所以在 Selenium 2.0 中并没有彻底地抛弃Selenium RC)。

Selenium 3.0

2016 年 7 月,Selenium 3.0 悄悄发布第一个 beta 版。Selenium 3.0 与 Selenium 2.0 最根本的区别并不是太大,最主要的变化如下:

  1. 去掉了对 Selenium RC 的支持。
  2. 只支持 Java 8 及以上版本。
  3. 对 Driver 方面的改动,增加了对 Safari 和 Edge 浏览器的支持;同时不再提供默认浏览器支持,所有支持的浏览器均由浏览器官方提供相应的 Driver 驱动进行支持,从而提高了自动化测试的稳定性。

WebDriver 协议如今已经成为各浏览器提供商共同支持的官方标准,也成了业内公认的浏览器 UI 测试的标准实现,因此 Selenium 3.0 的核心仍然是 WebDriver。

重要意义

  1. WebDriver 协议现在已经成为业内公认的浏览器 UI 测试的标准实现,该协议是 Google 对开源测试领域的重要贡献。
  2. 各种官方支持,意味着以后浏览器 UI 测试的速度和稳定性会有较大的提升。
  3. 浏览器 UI 自动化测试已经成为了行业标配。
  4. Selenium 专注 Web 测试。

 

posted @ 2021-07-06 17:21  Juno3550  阅读(2509)  评论(0编辑  收藏  举报