这篇文章来自我们团队的李翊豪同学,他准备写一个系列的文章,来分享基于录制回放、截图对比的UI自动化测试心得。这是他的第一篇,对UI自动化测试感兴趣的小伙伴快来看看吧~
前言
提到质量保障,自动化测试总是一个绕不开的话题,而 Selenium 作为 WebUI 自动化测试工具中的佼佼者,经常被拿来跟各种工具比较。 在我刚开始调研自动化测试方案时,经常被 Selenium IDE、Selenium Grid、Selenium Webdriver、Selenium RC、WebdriverJs 等一堆工具绕晕,甚至很多文档中将某个工具简称为 Selenium,这对不了解上下文和这些工具差异的我造成了很大困扰,本文将 Selenium 框架中的各个工具整理说明,希望能帮助大家理解这些工具。
Selenium 发展史
Selenium 通常被认为是一个 WebUI 自动化测试工具,但严格来说,Selenium 并不能被称为一个工具,实际上它由多个工具或应用组成,可以说它是一套完整的测试解决方案,或者 Selenium 全家桶。因为 Selenium 曲折的发展历史,导致了我们现在在不同上下文中,Selenium 所指的内容是不一样的,所以我们将从 Selenium 的发展历史着手,依次介绍 Selenium 各版本中出现的工具。
Selenium Core
2004 年,Thoughtworks 的工程师 Jason Huggins 正在负责一个 Web 应用的测试工作,由于这个项目需要频繁回归,这导致他不得不每天做着重复且低效的工作。为了解决这个困境,Jason 开发了一个运行在 JavaScript 沙箱中的 E2E 测试工具,并将其命名为 JavaScript Test Runner 的工具。
后来他的团队在此基础上完善了很多 API,这个工具后来被称为 Selenium Core,也是 Selenium 的雏形。这时的 Selenium Core 只支持 JS 编写的测试脚本,且只能在本地运行。
Selenium 1
后来 Selenium Core 团队在之前的基础上,发布了三个新工具:Selenium IDE、Selenium Grid、Selenium RC(RC 是 Remote Control 的简写),这就是第一版 Selenium。所以 Selenium 1 指的是这三个工具所组成的系统。
Selenium IDE 用来录制及回放简单的测试用例脚本;Selenium Grid 用来支持分布式运行测试脚本;Selenium RC 用来在浏览器中执行测试脚本。 (关于这些工具的核心模块以及执行过程,我放在了文章结尾,有兴趣的小伙伴可以详细看看)
Selenium 1 的发布,让多种不同语言的开发者可以控制浏览器,很多之前需要人工完成的工作得以自动化。
但 Selenium 1 仍有不少问题,比如它不能捕获本机的键盘和鼠标事件。
WebDriver
在 Selenium 1.0 发布的 2006 年,Google 工程师 Simon Stewart 发起了一个名为 WebDriver 的项目。它也是一个自动化测试工具,彼时刚刚起步,后来它也将成为 Selenium 的竞品之一。
导致 Selenium 1 各种问题的一个主要原因是,Selenium 是通过在浏览器中注入 JavaScript 应用,并通过执行应用中的各种 JS 函数来实现对浏览器的控制。而 Simon 希望 WebDriver 能通过浏览器提供的 API 来直接操作浏览器,借此来规避在 JS 沙箱中的各种限制。
经过几年的发展,WebDriver 通过与各浏览器的集成,成功实现了在外部直接控制浏览器行为的目标,同时 WebDriver 还利用操作系统级的调用,支持模拟用户输入。同时 WebDriver 还针对不同浏览器有着不同的策略,比如当操作 Firefox 浏览器的时候,WebDriver 是用 JavaScripts 来调用 API 的;而当我们操作 IE 浏览器的时候,WebDriver 就用 C++ 了。
直到这时,WebDriver 成为了 Selenium 1 的有力竞争者。
Selenium 2
2009 年,在 Google 测试自动化会议上,两个团队的开发人员在沟通后决定合并这两个项目,新项目被命名为 Selenium Web Driver,也就是 Selenium 2.0。
WerDriver 的作者是这样解释二者合并的原因的:“一方面 WebDriver 解决了 Selenium 存在的缺点(例如可以绕过 JavaScript 沙箱,WebDriver 有出色的API),另一方面是 Selenium 解决了 WebDriver 存在的问题,还有就是 Selenium 的主要贡献者和我都以为合并项目是为用户提供最优秀框架的最佳途径。”
Selenium 2 在保留 Selenium 1 体系的基础上,加入了来自 WebDriver 的清晰面向对象 API,不再限于在 JS 沙箱中运行,支持多种浏览器和多语言绑定,总之它提供了极佳的体验(考虑向下兼容性,Selenium 2.0 中并没有彻底地抛弃 Selenium RC)。在这个版本之后,Selenium 的结构设计、数据流转方式基本成型,后续版本不再像之前一样有破坏性的变更,更多的是对局部功能的重构和优化。
Selenium 3
2016 年,Selenium 3 发布。这个版本并没有引入新的工具,主要加强了对浏览器的支持。
相较 Selenium 2 的主要的变动有:
- 完全移除了 Selenium RC。
- WebDriver 暴露一个供浏览器接入的 API,通过各浏览器厂商提供的 Driver 来接入。
- 将 Firefox Driver 剔除(之前 Firefox Driver 是内置的)。
- 支持 Firefox 通过 GECKO Driver 来接入 Selenium。
- 通过 Apple 提供的 Safari Driver,Selenium 可以支持 Safari 接入。
- 通过 Edge Driver 支持 IE 接入。
通过 Selenium 团队的努力,以及各浏览器厂商的支持,Selenium 所使用的方法已经逐渐成为行业标准。2018 年 6 月,WebDriver 成为 W3C 推荐应用,Mozilla、Google、Apple、Microsoft 陆续支持 WebDriver,并不断改进浏览器和浏览器控制代码,从而使不同浏览器之间的行为更加统一,自动化脚本的运行更加稳定。
Selenium 4
2021 年,Selenium 发布 Selenium 4。
在 Selenium 3 中,与浏览器的通信基于 JSON-wire 协议,因此 Selenium 需要对 API 进行编解码。而 Selenium 4 遵循 W3C 标准协议,Driver 与浏览器之间通信的标准化使得他们可以直接通信。
除此之外,Selenium 4 还做了很多改动。包括:
- 优化了对浏览器的支持。
- 使用新的设计优化了 Selenium Gird。
- 标准化了 Selenium 的文档(你敢信从 Selenium 2.0 开始,文档就没更新过…)。
- IDE 中的 CLI Runner 变更为基于 NodeJS(之前是 HTML Runner)。
- Client 和 Driver 支持了新的元素定位 API。
- 支持屏幕截图。
- 改进了 Chrome Dev Tools。之前 Chrome Driver 直接继承自 Remote Web Driver 类,现在继承自
Chromium Driver 类,这个改动使得 IDE 开发可以使用更多的 API。
在编写这篇文档时 Selenium 刚刚发布 4.4.0(2022 年 9 月),现在的 Selenium Client 及 WebDriver 已经支持 C#、Ruby、Java、Python、JavaScript 等多种语言。
演进过程图
Selenium 中的数据通信原理
关于 Selenium 1 中的工具以及它们的主要模块
Selenium 1 由 Selenium IDE、Selenium Grid、Selenium RC 三个工具组成,下面让我们详细看看这些工具以及他们的主要子模块都做了些什么。
其实早在 2006 年,Selenium 团队就发布了 Selenium 1.0,但彼时只有 Selenium IDE、Selenium RC 两个工具。 直到 2008 年,ThoughWorks 的另一位工程师 Philippe Hanrigou 主导开发了 Selenium Grid,并在后续的版本中加入了 Selenium 全家桶内。 我们通常提到 Selenium 1 也指的是 2008 年之后加入 Selenium Grid 的这个版本。
Selenium IDE 是一个 Firefox 的扩展,用于录制和回放浏览器中的操作。它提供了至少两个便利:1. 测试人员可以用它快速生成简单用例;2. 如果测试过程中发现 Bug,测试人员也可以将复现步骤录制下来,以便开发人员复现。
Selenium Grid 是用来提升测试效率的辅助工具,它提供了一个中心服务,支持同时在多个环境中运行不同的用例,而且还支持远程。它使得 Selenium 支持分布式测试,从而有效地提高测试效率。
Selenium RC 是整个系统的核心,它支持多种不同语言编写的脚本,通过 Selenium Server 作为代理服务器去访问应用从而完成测试,使用浏览器内置的 JavaScript 解释器来解释和执行 Selenese(Selenese 是 Selenium 命令的集合)。Selenium RC 包含 Client Libraries 和 Selenium Server 两部分,而 Selenium Server 又主要包含 Launcher、Core、Http Proxy 三个部分,下面我们分别介绍。
Client Libraries,你可以将它理解为一个工具库,它是 Selenium Server 提供的 API 的集合,主要用于编写测试脚本。
Selenium Server 用来控制浏览器行为,它主要包含三个部分:
Selenium Launcher 用于启动浏览器,把 Selenium Core 加载到浏览器页面当中,并把浏览器的代理设置为 Selenium Server 的 Http Proxy。
Selenium Core 是一个带断言库的 test suite runner,由 Selenium Server 注入到浏览器中,它是 JavaScript 函数的集合,Selenium 通过这些函数对浏览器进行操作。
Selenium HTTP Proxy,顾名思义就是个代理服务,接受和处理脚本的 HTTP 请求。
Selenium 1 初始化的过程
启动测试脚本(脚本中包含要测试的网页地址,以及相关环境配置)
脚本发送启动请求给 Selenium Server,请求中包含要测试的网页地址、本次测试的浏览器等信息
Selenium Server 收到请求后,做了如下工作:
使用 Launcher 打开浏览器
将浏览器的代理指向 Selenium HTTP Proxy 服务
使用浏览器打开要测试的网页地址
Selenium HTTP Proxy 收到浏览器打开网页的请求
Selenium HTTP Proxy 请求被测试的目标服务器并拿到网页内容
Selenium HTTP Proxy 向网页中注入 Selenium Core 后将其返回给浏览器
Selenium 1 的执行过程
- 测试脚本将要执行的 Selenese 指令(Selenese 是 Selenium 命令的集合)发送给浏览器
- 浏览器中的 Selenium Core 解释和执行这些指令
- 在执行过程中,涉及到与被测试的目标服务器交互的流量都会先发送到 Selenium HTTP Proxy
- Selenium HTTP Proxy 将这些请求发送给对应的 Web Server
- Selenium HTTP Proxy 拿到响应后返回给浏览器,并以此实现与浏览器中 Selenium Core 的通信
本条指令执行完成,开始执行下一条指令
Selenium 2 中的 Web Driver 为什么比 Selenium 1 更强大
在了解了 Selenium 1 的初始化及执行过程后,我们来看看 Selenium 2 比 Selenium 1 强在哪。
其实 Selenium 1 和 2 最大的区别就在于就在于二者控制浏览器的方式。相比于 Selenium 1 在浏览器中注入代码,并在沙箱中运行 JS 函数来操作浏览器。 Web Driver 是从更高的维度来解决这事,他们设计了一套规则(命名为 The Web Driver Wire Protocol,也叫 WebDriver Wire 协议),然后要求浏览器厂商来支持这套协议,这样就可以从外部通过浏览器本身提供的 API 来控制浏览器,而不用等到页面的 runtime 阶段,同时也规避了非常多的限制,理论上可以通过它控制浏览器的所有行为。
还有个好处是,WebDriver Wire 协议是通用的,它是靠各浏览器厂商提供的驱动来接入的,这些浏览器在启动之后会同时启动一个基于这套协议的 Web Service。比如,FirefoxDriver(彼时的 Firefox 还没有支持 GECKODriver)在启动之后会在 7055 端口启用这一服务,ChromeDriver 会在 46350 端口启动这一服务。
后续我们通过 ComandExecutor 来发送命令,也就是发送一个 HTTP 请求给这个 Web Service,在这次请求的 body 中,会按照 WebDriver Wire 协议规定的格式来告诉 Selenium 我们希望浏览器做什么。而浏览器也需要依赖驱动解释这些指令,并执行相应的浏览器内部 API。
背后小故事
从 Selenium Core 到 Selenium 1 的故事
Selenium Core 项目开源后迎来了很多优秀的开发者参与,当然 ThoughtWorks 内部也在积极参与,这使得 Selenium 的配套迅速完善了起来。
ThoughtWorks 的开发者 Paul Hammant 在 Selenium Core 的基础上主导开发了 Selenium RC,这个工具也成为 Selenium 1 的核心工具。
同在 ThoughtWorks 的 Patrick Lightbody 主导开发了名为 Hosted QA 的 Java 应用,它让 Selenium Core 可以分布式运行,后来更名为 Selenium Gird。
同时,开源社区中的日本开发者 Shinya Kasatani(谷谷真也) 将 Selenium Core 的核心代码包装到 FireFox 的 IDE 模块中,从而实现记录/回放测试过程。后来他向 Selenium 开源项目捐赠了这个工具,命名为 Selenium IDE。
至此,Selenium 1 体系完备,并于 2006 年正式发布。
关于 Selenium 命名的故事
当时主流的自动化工具是惠普开发的 QTP Mercury,这个工具并不开源,Mercury 这个单词表示化学元素汞。团队将其命名为 Selenium 并开源,是因为 Selenium 所表示的化学元素硒可以用来降低汞的毒性。
现在我邀请你进入我们的软件测试学习交流群:【
746506216
】,备注“入群”, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路。
喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一 键三连哦!