Selenium与Cypress的概览
作为一种广为流行的自动化开源测试框架,Selenium主要被用于Web应用测试和跨浏览器测试的场景中。Selenium WebDriver是Selenium套件的关键组件之一。
目前,Selenium支持诸如Python、Ruby、C#、JavaScript、Java、PHP等多种编程语言。它支持的自动化框架包括:Behave(一种流行的BDD框架)、JUnit、SpecFlow、MSTest、TestNG、PyTest、PyUnit、Mocha JS、Jest、WebDriverIO、以及Protractor等。
在使用Selenium开展自动化测试之前,开发人员需要在测试主机上下载并安装相应的浏览器驱动程序(如,Chrome的ChromeDriver、Firefox的GeckoDriver等),以及适当的Selenium语言驱动。
开源的Cypress项目目前被托管在GitHub上,其最新的版本是5.5.0。开发人员能够通过Cypress进行单元测试,编写端到端测试,以及开展集成测试。
与能够支持多种语言的Selenium WebDriver不同,Cypress仅能够支持JavaScript,不过它是精通JavaScript前端开发和自动化测试人员的首选。在对测试自动化框架的支持方面,Cypress仅支持Mocha JS框架。因此,我们可以认为Cypress的Web自动化测试用例,只在Mocha JS框架上,运用JavaScript编写而成的。
下图是Selenium WebDriver和Cypress,在过去六个月的下载趋势图。可见Cypress的下载量正在慢慢赶上Selenium。
下载比较图
来源--https://www.npmtrends.com/protractor-vs-selenium-webdriver
Selenium简介
Selenium项目始于2004年。2006年推出的Selenium IDE,是一款原生的记录和回放工具,仅能够使用在Firefox上。当然,最新的Selenium IDE已经可以被用在Chrome上了。它不但带有跨浏览器的支持,可用于并行测试,而且能够让自动化测试人员通过设置断点,来调试脚本。
当前,Selenium的最新稳定版本是Selenium 3.141.59。不过,Selenium 4(仍处于Alpha阶段)中的Selenium WebDriver是W3C的建议版本。由于JSON Wire协议将不再被用于与Web浏览器进行通信,因此自动化测试将能够更加无缝地协同工作在不同的浏览器(如Chrome、Firefox等)之间。
Selenium WebDriver架构
由于Selenium WebDriver和相应的浏览器使用通用的协议(即W3C协议)进行通信,因此开发人员往往认为Selenium 4具有更稳定且统一的特点。
Selenium的主要优点
- Selenium WebDriver能够被广泛地用于单元测试、E2E(端到端)测试、以及安全性测试。
- 如前所述,Selenium支持多种流行的编程语言,并广泛用到了各种自动化测试框架。
- 它既兼容最新的浏览器(如Chrome、Firefox、Edge等),又兼容Internet Explorer等过时的浏览器。
- 经过常年的积累,Selenium拥有不断壮大的生态系统。
- 可以将本地的Selenium测试用例,轻松地移植到基于云端的Selenium Grid处。
- Selenium能够与LambdaTest之类的云端测试工具开展并行测试。这不但可以减少测试时间,提高成本效益,还能够实现更大的测试覆盖率。
Selenium的缺点
- 对于新手来说,Selenium的学习曲线比较陡峭。当然,开发人员和自动化测试人员也可以通过向Selenium社区里的活跃用户学习,来快速入门。
- 由于涉及到安装浏览器的驱动程序、Selenium Grid服务器、以及Selenium IDE,因此Selenium的设置过程较为耗时。
- 尽管Selenium被广泛地用于UI测试,但它在测试图像方面存在着局限性。
- 由于Selenium脚本是在浏览器外部被执行的(即,测试脚本和被测浏览器之间的接口是通过相应的“浏览器驱动程序”来实现的),因此它比Cypress框架执行的时间会更长。
Cypress简介
Cypress是为开发人员和质量保证工程师打造的下一代前端测试工具,可被用来测试浏览器中运行的所有内容。与Selenium运行在浏览器外部不同,Cypress能够与应用程序在同一循环中被执行。也就是说,节点服务器(Node server)的进程能够与Cypress相互通信,同步并执行任务。由于可以访问到网络层,因此Cypress能够即时读取和更改网络的流量。
凭借着独特的DOM操作技术,Cypress的各项测试皆可访问到DOM中的Web元素、应用实例、计时器、以及服务worker等内容。
由于对自动化过程具有完全的掌控力,因此Cypress可以修改进出浏览器的所有内容,以及那些可能会干扰Web浏览器自动化功能的代码。同时,因为Cypress被安装在本地,所以可以通过访问操作系统,来控制各项自动化任务。
Cypress的主要优点
- 由于测试用例直接运行在浏览器内部,因此在安装Cypress时无需任何依赖项,也无需额外的下载。
- 由JavaScript构建的Cypress,可被开发人员和质量保证工程师用于前端开发。
- Cypress没有额外的IDE负担。在启动Cypress时,它会提示您选择IDE,以方便更改测试脚本。
- Cypress进程可实时地响应应用事件,并处理各种命令。同时,通过Cypress中的实时重载功能,用户可以实现在应用发生变更时,自动重载测试。
- 由于Cypress对整个自动化过程(从上到下)具有严格的控制,因此它能够更好地了解浏览器内、外的变化,进而提供一致性的结果。
- 由于运行在应用程序内,因此Cypress的测试代码可以访问到应用程序所触及的所有对象(不限于DOM元素)。由此,Cypress不再需要JSON Wire(或其他协议)进行通信。
- 由于Cypress会自动等待DOM中元素的生成,因此用户无需在Cypress中添加隐式和显式的wait语句。在执行到下一条语句之前,Cypress也会等待命令和声明(https://on.cypress.io/introduction-to-cypress#Cypress-is-Not-Like-jQuery)。此外,Cypress也不会产生不属于DOM的陈旧元素。
- 由于测试是在浏览器内部执行的,并且Cypress可以直观地获悉应用是如何进行同步的,它甚至知道某个元素对于动画效果处理的起、停时间(https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Animations)。因此,与使用其他自动化测试工具相比,Cypress的测试具有更高的抗剥离性(flake resistant)。
- Cypress会捕获每个测试步骤的快照,以方便开发人员可以在测试脚本中的任何特定步骤上,检查其活动状态。
- Cypress可让用户直接修改DOM元素,例如:显示某些隐藏元素。
- 由于是基于Electron App构建的,因此Cypress可以让开发人员或质量保证工程师,通过使用Stubbing DOM API,来更好地控制应用程序。
- Cypress中的Stubs [如cy.stub()] 可用于修改某些功能,并将其控制权委托给开发人员。Cypress中的Spies [如cy.spy()] 则让用户可以监控某个功能。Cypress中的时钟API [如cy.clock()]可用于控制应用程序的数据和时间。这些都有助于按需替换应用的原有行为,或避免在测试中出现缓慢情况。
- 鉴于UI测试之类的活动可能并不需要执行分析,因此开发人员可以在应用执行测试之前,阻止Google Analytics之类的分析代码。
- Cypress允许开发人员像在单元测试中那样,人工创建不同的状态。此过程并不会拖慢整个测试进程。
- Cypress通过丰富而直观的用户界面和仪表板,向用户展示了测试被执行的每一个细节,包括:声明、网络请求、页面加载、stubs、以及监控等。
- 默认情况下,它能够支持并行测试(或称并行化)。同时,它能够让用户按照浏览器、测试标签等条件,对测试进行分组。下图便是Cypress并行测试的简短过程:
来源--https://docs.cypress.io/img/guides/parallelization/parallelization-overview.88fddb02.png
- Cypress还可以与流行的CI/CD工具相集成,其中包括:Jenkins、Bamboo、Circle CI、Bitbucket、GitLab等。
Cypress的缺点
- 它仅支持使用JavaScript框架创建的测试用例。
- 它不支持远程执行。
- Cypressk在其网站声称,Cypress将永远不会支持处理多个浏览器选项卡。
- 默认情况下,Cypress并不支持多个浏览器的实例,也不能同时控制多个已打开的浏览器。对此,Cypress目前的解决方法(https://docs.cypress.io/guides/references/trade-offs.html#Multiple-browsers-open-at-the-same-time)是通过与其他后端进程(如,Selenium、Puppeteer等)同步,以驱动另一个已打开的浏览器的实例。
- 目前,Cypress的测试仅限于用来确定具有相同来源的访问域,因此用户无法在同一测试中,访问到不同来源的两个域。当然,他们可以访问在不同测试中,不同来源的两或多个域。
Selenium跨浏览器测试入门
您可以选择使用本地Selenium Grid,或是在LambdaTest之类基于云端的Selenium Grid上,进行可扩展的跨浏览器测试。
- 若要在本地Selenium Grid上进行跨浏览器测试,您必须事先安装浏览器的驱动程序,并在被Selenium支持的C#、Java、Python、Ruby等语言中选择一种。
- 若要在云端Selenium Grid上执行Selenium自动化,您必须在该平台上创建一个帐户,并在代码中调用适当的浏览器功能。
下面,我们来讨论一个使用Selenium进行自动化测试的示例:
在Windows 10上的Chrome 86.0中输入URL https://lambdatest.github.io/sample-todo-app/。
选择前两个复选框。
将“Happy Testing at LambdaTest”发送到id为sampletodotext的文本框处。
单击添加按钮,并验证是否已添加了该文本。
如果与预期的窗口不匹配,则需要声明。
下面是在LambdaTest的云端Selenium Grid上进行测试的Java代码:
Cypress自动化测试入门
由于Mocha框架运行在Node.js上,因此在安装Cypress之前,您需要安装依赖项软件包:Node JS和类似Visual Studio Code的IDE。
在安装好Node JS后,我们可以使用Node软件包管理器npm,从终端上安装Mocha和Cypress。
请在终端上运行以下命令,以安装Mocha:
- npm install mocha
请在终端上运行以下命令,以安装Cypress:
- npm install cypress
如上图绿色框所示,Cypress5.5.0已成功安装。接着,我们通过如下命令,来启动Cypress:
- npx cypress open
它将打开Cypress仪表板,以便运行各种测试:
Cypress在\integration\examples中提供了各种示例脚本:
若想快速检查测试,应将脚本放在同一个文件夹中。我们参照上述Selenium的测试案例,额外添加了wait usingcy.wait()方法,以及用于从DOM处获取所需的Web元素的cy.get()方法。
Cypress随附了丰富的API集,以及特定于浏览器的,诸如:执行按钮单击,设置视图等命令。
在以上代码中,cy.visit()用于打开特定的URL。它类似于driver.getSelenium。cy.get()方法则用于在DOM中定位特定的Web元素。一旦访问到了某个元素,就可以在该元素上执行适当的操作了。例如,我们找到元素--#sampletodotext,便可在文本框中输入“Happy Testing at LambdaTest”。cy.log()方法用于将消息打印到Cypress的控制台日志中。
在Cypress中,我们可以轻松地通过cy.contains()方法,来获取包含特定文本的DOM元素。
在安装了Cypress的主机上,有Chrome 86、Firefox 82、Edge 86和Electron 85,四种浏览器可供选择。
因此,为了执行上述测试,我们只需导航至Cypress仪表板中的测试标签,在首选浏览器(如Chrome 86)中单击测试文件(即Cypress_ToDoApp.js)即可。下图是正在进行的测试快照:
测试成功的快照如下图所示。可见,Cypress能够实时地显示执行状态,并提示代码中是否存在问题。
Cypress可简化Web App测试
Cypress在如下方面大幅简化了开发人员和质量检查工程师的工作。
查找网络元素
从Cypress的实现可以看出,Web元素没有使用标准的Web定位符(即XPath、Name等)来予以标识。那么,脚本将如何在DOM中定位元素呢?
Cypress在测试运行器中具有一项被称为“Selector Playground”的出色功能,可方便查找Web元素。您可以在待测试的URL旁,单击“Open Selector Playground”按钮,然后将鼠标悬停在需要提供详细信息的元素上。
通过点击该Web元素,其详细信息将会填充并显示在“cy.get”或“cy.contains”中(紧挨着显示测试文件名的区域)。
由于“Selector Playground”类似于Chrome(或Firefox)中的检查工具,因此用户无需额外学习该功能,即可修改并执行目标代码。
时间点跳转(Time Travel)
由于Cypress在运行测试时会捕获快照,因此它能够灵活地追溯到曾经执行过的某个时间点。具体而言,您只需将鼠标悬停在命令日志中的某个命令上,然后检查该步骤曾经的历史记录即可。Cypress默认最多可以保留50个测试值的快照和命令数据。
下面显示的是在LambdaTest的ToDo页面上第一个元素(li1)被单击后,执行“时间点跳转”的截图。
可见,当您想在测试脚本中检查某个特定操作的效果时,“时间点跳转”功能就能派上用场了。
测试执行
如前所述,Cypress的测试是在浏览器内部执行的。由于被安装在本地,因此它可以获取Web浏览器内、外部发生的所有情况。这便是您可能不会察觉到Cypress测试中有任何网络延迟的主要原因。而且,由于Cypress使用的是与浏览器相同的DOM事件,因此其命令的执行速度要比Selenium快得多。
此外,Cypress使用Mocha的BDD语法,来实现单元测试和集成测试。Mocha JS本身提供了出色的异步支持。而Chai-jQuery、Sinn.JS和Sinon-Chai则为Mocha提供了编写带有错误消息的可读声明等功能。
下表是对上述讨论过的,有关Cypress和Selenium在不同方面的总结与比较。
该如何选择?
可见,Cypress是一个新兴且不断迭代的工具,而Selenium是自动化测试领域的成熟工具。如果您精通JavaScript,并且正在寻找可以在本地主机上执行自动化测试的工具,那么请选用Cypress。同时如果您的Web应用是使用React、Angular等时下流行的JavaScript框架构建的,并且对于跨浏览器测试的要求不高,那么也请选用Cypress。
如果您希望测试代码能够在各种浏览器和操作系统上流畅运行,则请使用Selenium。此外,由于Selenium测试也可以在基于云的Selenium Grid上执行,因此您可以用到由LambdaTest平台提供的大规模并行测试的优势。
总之,Selenium和Cypress没有绝对的完胜者,但是它们之间的确有着众多差异。您可以从实际项目的测试覆盖率需求、团队的技能储备、以及长远发展的角度,通过试用,来选择最适合的一种工具。
原文Selenium Vs. Cypress: Which Is Better in 2021?,作者:Himanshu Sheth
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】