随着互联网技术在全球范围内的迅速发展,各种基于浏览器的Web应用程序也已成为当今软件开发的主流。围绕如何更好、更有效的测试Web应用的技术也是层出不穷。Cypress和Selenium是目前广泛使用,且很有代表性的两种Web自动化测试工具。互联网上对Cypress和Selenium的讨论非常多。各大论坛上,针对谁是最佳Web自动化测试工具的争论也是此起彼伏。下面我截取了一些典型的讨论供大家参考。
“Is Cypress better than Selenium WebDriver? I get asked this a lot. Frankly, the easiest path of a ‘this vs that’ talk is to try and find out which is ‘best’. |
本文将以我在实际工作中的切身体会例举出Cypress与Selenium的各自优缺点,尽可能客观的进行分析比较。希望我的分析总结能对正纠结于选择最适合自己产品的Web自动化测试工具的朋友提供一些帮助。 ~ 工作原理 ~
Web自动化测试就是站在用户的角度测试Web应用程序业务逻辑的正确性。测试的重点是围绕Web服务暴露的接口检查其数据的正确性。这个过程是将Web应用程序当做黑盒,通过自动化测试技术提高测试执行的效率,降低人工回归的成本。这种端到端的测试离不开定位页面元素、获取页面元素信息以及操作页面元素三个核心要素。 Selenium和Cypress都是比较好的端到端自动化测试工具。但我们在各自的官方网站上不难看出,Selenium (https://www.selenium.dev/) 与Cypress (https://www.cypress.io/) 在工作原理上有着本质的区别。 Selenium
Selenium的核心是webdriver,如图 1所示。webdriver通过向浏览器发送指令来控制浏览器里加载的页面元素,进而完成和用户一样的页面操作。
图 1 Selenium工作原理 Cypress
Cypress 是在 Mocha API (https://mochajs.org/)的基础上开发的一套开箱即用的端到端测试框架。如图 2所示,Cypress 和 Webdriver的工作方式完全相反,它与应用程序在相同的生命周期里执行。具体来讲,在测试开始并首次加载Cypress时,Cypress Web内部应用程序先把自己托管到本地的一个随机端口上,然后使用webpack将测试代码中的所有模块绑定到同一个JavaScript文件中,启动指定的浏览器,并将测试代码注入到空白页面里,同时运行测试代码。当识别出测试脚本中发出的第一个cy.visit()命令后,Cypress将会更改其本地的URL以匹配远端应用程序的地址,使得测试代码和应用程序可以在一个生命周期中运行。
图 2 Cypress工作原理 ~
优缺点对比
~
任何自动化测试工具都有其独到的特点,Selenium和Cypress亦是如此。下面我们列举出Selenium和Cypress各自的优缺点,方便我们直观的进行比较。 Selenium支持更多语言和浏览器
由于webdriver提供了几乎所有浏览器的版本,因此,Selenium能在各种浏览器上运行自动化测试脚本。而Cypress目前还不支持所有浏览器。以下是Selenium与Cypress各自支持浏览器的列表对比。
Selenium与Cypress都支持诸如Windows、Mac以及Linux/Unix等操作系统。
Selenium支持多更多编程语言,而Cypress只支持JavaScript。以下是Selenium与Cypress目前支持的编程语言列表对比。
Selenium更易出现稳定性的问题
由于Selenium的核心是webdriver,而不同版本的浏览器又需要用对应版本的webdriver来驱动。因此,用selenium实现的自动化测试用例往往需要在配置文件中指定webdriver的版本号,如下代码所示。这就给测试用例的稳定性带来了一定的隐患。我们经常发现,有些浏览器由于自动升级,如果对应的webdriver没有得到及时的更新,导致测试用例突然出现大面积的运行失败。这时,我们不得不更新配置文件中的webdriver版本号来升级测试环境。然后,再重新调试测试用例确保它们都能在新版本的浏览器中稳定的运行。周而复始,这种维护工作量可想而知。
Cypress由于在运行测试用例时,使用webpack将测试代码中的所有模块绑定到同一个JavaScript文件中,同时将该JavaScript文件注入到Cypress启动浏览器的空白页面里,并在其中运行测试代码。这就起到了Cypress测试用例能与应用程序在相同的生命周期里执行的效果。它不需要Selenium webdriver的支持,更没有webdriver版本兼容的问题。因此,基于Cypress的测试用例更稳定。从下面的代码示例能看出,基于Cypress的测试用例比较简洁,且完全没有必要专门指定测试浏览器等环境的版本信息。
Cypress的运行速度更快
Cypress 测试代码和应用程序均运行在由 Cypress 全权控制的浏览器中。而且它们运行在同一个Domain 下的不同 iframe 中,所以 Cypress 的测试代码可以直接操作 DOM、Window Objects、Local Storages而无须通过网络访问。
反观Selenium,由于它所有的操作都需要发指令给webdriver,并通过webdriver启动对应的浏览器,然后在其中运行。这样的设计架构会带来运行同一操作的测试代码,在Selenium框架下会比在Cypress框架下耗费更多的时间。
Cypress提供自动等待的功能
用Selenium编写自动化测试用例的过程中,相信大家会有如下深刻的体会:
- 你看到页面跳转到你需要的位置了。
- 你也看到你想要的页面元素呈现在浏览器中了。
- 但是,Selenium还是报告错误说,没找到页面元素或该页面元素不可用。如以下错误所示。
解决以上的问题有时候就是多加一些等待时间,让页面元素充分加载到浏览器中,这样Selenium才能找到你想要的页面元素。
Cypress完美的解决了上述痛点,它能自动等待页面元素至可靠操作状态时才执行命令或断言。我们不难用下面的示例代码体会到,有了自动等待页面元素的功能,开发人员在开发和调试测试用例时,就可以完全忽略时序问题,把工作重心放在产品功能和操作上。
不同页面间的代码共享
我们知道有些单页面应用(SPA)中的页面元素,比如搜索框、导航菜单等,是在很多页面中复用的。这就使得我们在设计自动化测试脚本的时候需要有全局观,能事先把这些元素及其对应的操作封装成公共的函数,方便在不同页面间共享。
在Selenium中,一个比较普遍的方法就是基于页面模块来设计。我们常常称这种方法为面向页面的设计模式(Page Object Model)。以下代码示例展示了如何按照页面来封装对象。这种设计方法的最大好处就是可以在相同页面中或者不同页面间共享代码,使得对页面元素的操作如同调用普通函数一样简单。
然而,在Cypress中却并没有类似的概念,取而代之的是方法和命令。具体来讲,在同一个测试脚本中,开发人员可以把一些公共的操作(例如获取导航栏、获取搜索栏等)封装成函数。也可以把一些页面间公共的操作(例如登录系统等)放到命令文件里。这就起到了测试用例间共享代码的作用。命令文件可以在工程目录下的cypress/support/commands.js位置找到,命令示例如下所示。有关Cypress命令的详细介绍请参见其官方网站https://docs.cypress.io/api/cypress-api/custom-commands.html#Syntax。
运行环境搭建
Selenium的运行环境搭建本身不太复杂,但它相对与Cypress还是要稍微复杂一些。我们从图 3不难看出这一点。
图3 有了Cypress一切看似简单
结合我的实际经验,通过下表我例举了一些重要步骤做具体对比。需要注意的是,有关Selenium的运行环境搭建步骤是在Java开发语言的前提下展开的。
~ 各自独有的特性 ~
Selenium和Cypress都有各自独有的一些特性。由于篇幅原因,本文只列出一些典型的特性供大家参考。
Selenium IDE
Selenium提供了可以运行在Chrome和Firefox浏览器上的插件,如图 4所示。该浏览器插件就是Selenium IDE。它提供的录制、回放等功能,特别适合初次接触Selenium的用户。用户在不知如何编写测试代码时,可以用Selenium IDE直接把页面上的操作录制下来并产生对应的代码供参考。
图4 Selenium IDE界面截图
Cypress提供了更多的API
由于Cypress相较于Selenium独特的框架设计,使得Cypress在运行自动化测试用例的过程中能与Node.js频繁的交换、同步彼此信息。因此,Cypress可以访问并操作系统网络层和文件系统。从而使得截取、录制屏幕等操作变得非常容易。而且,Cypress的运行速度相较于Selenium更快。翻看Cypress官方文档,你会发现Cypress不光可以定位、操作页面元素,它还可以直接发送HTTP消息给待测web应用程序并将其响应无缝的展现在浏览器里面。总之,Cypress可以自上而下的控制自动化测试的整个进程。有关Cypress API的更多描述信息请参考其官方文档https://docs.cypress.io/api/api/table-of-contents.html。
~ 总结 ~
Selenium和Cypress都是目前在GitHub上比较活跃的开源项目。图 5展示了Selenium从2004年项目之初到今天一直有源源不断的代码提交。而Cypress是在2014年才开始的,是比较新的项目,如图 6所示。但它在6年的发展过程中,提交了大量的代码,功能不断完善。Cypress的代码峰值提交量甚至超过了Selenium,可见Cypress的发展速度的确非常迅猛。这也从侧面证明了Cypress虽然是比较新的项目,但它提供的功能得到了业内越来越多同行的认可,成为了Web自动化测试工具的新星。
图5 Selenium代码提交数量
图 6 Cypress代码提交数量
Selenium作为老牌Web自动化测试工具,支持更多的编程语言和浏览器,像python易学、会Java的人多,得到了业内人士的广泛使用。Selenium IDE提供的录制、回放等功能拉低了Selenium的上手门槛。而Cypress独特的框架设计使得Cypress在运行自动化测试用例的过程中可以自上而下的控制自动化测试的全进程,且运行速度更快、更稳定。
参考文献
- Selenium官方网站:https://www.selenium.dev/
- Selenium官方文档:https://www.selenium.dev/documentation/en/
- Cypress官方网站:https://www.cypress.io/
- Cypress官方文档:https://docs.cypress.io/guides/overview/why-cypress.html
- 前端自动化测试框架Cypress入门:https://zhuanlan.zhihu.com/p/149256830
- Cypress 框架的详细介绍
作者之前发布的文章:
- 自主开发TAF之心路历程:基于Spock的测试自动化框架Honeycomb
- 超越Selenium的Web自动化测试:Geb技术