Skip to main content
Cypress应用

使用Cypress进行持续集成

info
你将学习到
  • 如何在持续集成(CI)中设置Cypress
  • 如何在CI中运行Cypress、录制测试并并行运行测试
  • 如何配置使用Cypress Docker镜像的CI工作流
  • 操作系统、依赖项、缓存和环境变量的高级配置

什么是持续集成?

设置CI

基础

在持续集成中运行Cypress与在本地终端运行几乎相同。通常只需要做两件事:

  1. 安装Cypress
npm install cypress --save-dev
  1. 运行Cypress
npx cypress run

根据使用的CI提供商,可能需要配置文件。请参考CI提供商的文档了解在何处添加安装和运行Cypress的命令。更多配置示例请查看我们的示例

启动服务器

挑战

通常需要在运行Cypress之前启动本地服务器。启动Web服务器时,它会作为一个长时间运行的进程持续运行。因此,需要让它在后台运行,否则CI提供商将无法执行后续命令。

将服务器进程放在后台意味着CI提供商在发出启动服务器的信号后会继续执行下一条命令。

许多人会使用类似以下的命令:

npm start & cypress run // 不要这样做

问题在于——如果服务器需要时间启动怎么办?无法保证下一条命令(cypress run)运行时Web服务器已经启动并可用。因此,Cypress测试可能在服务器准备就绪前就开始尝试访问本地服务器。

解决方案

幸运的是,有一些解决方案可以解决这个问题。与其引入任意等待(如sleep 20),可以使用更好的选择。

wait-on模块

使用wait-on模块,可以阻塞cypress run命令的执行,直到服务器启动完成。

npm start & wait-on http://localhost:8080
cypress run
info

大多数CI提供商会自动终止后台进程,因此无需担心在Cypress完成后清理服务器进程。

但如果要在本地运行此脚本,则需要更多工作来收集后台PID并在cypress run后终止它。

start-server-and-test模块

如果服务器启动时间非常长,我们建议尝试start-server-and-test模块。

npm install start-server-and-test --save-dev

package.json的scripts中,传递启动服务器的命令、服务器托管的URL和Cypress测试命令。

{
"scripts": {
"start": "my-server -p 3030",
"cy:run": "cypress run",
"test": "start-server-and-test start http://localhost:3030 cy:run"
}
}

在上面的示例中,cy:run命令只有在URLhttp://localhost:3030返回HTTP状态码200时才会执行。测试完成后服务器也会关闭。

注意事项

使用webpack-dev-server且不响应HEAD请求时,使用显式的GET方法ping服务器:

{
"scripts": {
"test": "start-server-and-test start http-get://localhost:3030 cy:run"
}
}

当在webpack中使用本地https时,设置环境变量以允许本地证书:

{
"scripts": {
"start": "my-server -p 3030 --https",
"cy:run": "cypress run",
"cy:ci": "START_SERVER_AND_TEST_INSECURE=1 start-server-and-test start https-get://localhost:3030 cy:run"
}
}

录制测试

Cypress可以录制测试并将结果保存在Cypress Cloud中。Cloud让你可以访问录制的测试——通常在CI提供商中运行Cypress测试时——并提供测试运行时的详细信息。

录制测试可以让你:

  • 查看失败、挂起和通过的测试数量。
  • 获取失败测试的完整堆栈跟踪。
  • 查看测试失败时和使用cy.screenshot()时截取的屏幕截图。
  • video配置启用时,观看整个测试运行的视频或测试失败时的片段。
  • 查看并行化时每台机器运行的测试。

录制测试步骤:

  1. 设置项目以录制
  2. 在CI中向cypress run传递--record标志
cypress run --record --key=abc123

阅读Cypress Cloud的完整指南。

并行运行测试

Cypress可以在多台机器上并行运行测试。

需要参考CI提供商的文档了解如何在CI环境中设置多台机器。

一旦CI环境中有多台机器可用,可以传递--parallel标志使测试并行运行。

cypress run --record --key=abc123 --parallel

阅读并行化的完整指南。

Cypress Docker镜像

CI提供商,如GitHub ActionsCircleCI,允许使用Docker容器镜像运行工作流。

Cypress通过提供官方Cypress Docker镜像支持Docker的使用。镜像是基于Linux的,支持以下平台:

  • Linux/amd64
  • Linux/arm64

Cypress Docker镜像提供了专为Cypress使用而定制的稳定环境。通过选择合适的Cypress Docker镜像,可以确定运行Cypress测试的确切环境。这样可以屏蔽CI提供商所做的版本更新,例如如果他们更新了Node.js或浏览器版本。

Cypress Docker镜像可从以下位置获取:

Cypress Docker变体

  • cypress/base是入门级的Cypress Docker镜像,允许在Cypress内置的Electron浏览器中进行测试。它包含完整的Linux (Debian)操作系统,以及Cypress的必备操作系统包、Node.js、npm和Yarn v1 Classic。镜像<tag>可以选择Node.js版本。

  • cypress/browsers基于cypress/base镜像构建。对于Linux/amd64镜像,它添加了ChromeFirefoxEdge浏览器。对于Linux/arm64镜像,仅从版本136.0.2及以上添加了Firefox浏览器。Chrome和Edge浏览器目前不适用于Linux/arm64。相应的镜像<tag>可以选择Node.js和浏览器的组合版本。对于Linux/arm64平台上不可用的Chrome和Edge浏览器,版本标签仅为占位符,用于多平台支持兼容性。

  • cypress/included基于cypress/browsers镜像构建。它添加了固定版本的Cypress,通过npm全局安装。短格式镜像<tag>选择Cypress版本。相应的长格式<tag>选择Cypress版本并记录Node.js和浏览器的组合版本。

  • cypress/factory提供基础操作系统镜像,并允许按版本单独选择其他组件。用于生成自定义Docker镜像。

CI Docker示例

可以在下面找到使用Cypress Docker镜像的示例

CI示例

AppVeyor

AWS Amplify Console

AWS CodeBuild

阅读我们关于如何在AWS CodeBuild中设置Cypress的详细指南。

Azure Pipelines

Bitbucket Pipelines

阅读我们关于如何在Bitbucket Pipelines中设置Cypress的详细指南。

CircleCI

阅读我们关于如何在CircleCI中设置Cypress的详细指南。

Buildkite

CodeShip Pro

GitHub Actions

阅读我们关于如何在GitHub Actions中设置Cypress的详细指南。

GitLab

阅读我们关于如何在GitLab中设置Cypress的详细指南。

Jenkins

Netlify

我们推荐使用官方的netlify-plugin-cypress在部署到Netlify平台前后执行端到端测试。阅读我们的教程使用一行代码在Netlify上运行Cypress测试

Semaphore

TravisCI

高级设置

机器要求

运行Cypress的硬件要求取决于浏览器、被测应用程序和服务器(如果在本地运行)运行测试所需的内存,以避免崩溃。访问我们的系统要求指南获取最低硬件推荐。

一些迹象表明机器可能没有足够的CPU或内存运行Cypress:

可以通过运行cypress info命令查看机器的总可用内存和当前空闲内存。

npx cypress info
...
Cypress Version: 13.6.6 (stable)
System Platform: linux (Debian - 11.6)
System Memory: 73.6 GB free 48.6 GB

可以通过以下命令查看CI机器上的CPU参数。

node -p 'os.cpus()'
[
{
model: 'Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz',
speed: 3399,
times: { user: 760580, nice: 1010, sys: 158130, idle: 1638340, irq: 0 }
}
...
]

示例项目及其在CI上运行的机器配置:

**提示:**如果较长规格的测试有问题,尝试将它们拆分为较短的规格。

依赖项

Cypress可以在许多CI提供商的虚拟机环境中开箱即用,无需安装额外的依赖项。

Linux

如果在Linux CI环境中运行Cypress时看到缺少依赖项的消息,请参考Linux先决条件列表获取指导。

缓存

Cypress将其二进制文件下载到全局系统缓存——在Linux上是~/.cache/Cypress。通过确保此缓存在构建之间持久化,可以避免大型二进制文件下载,从而节省安装时间。

我们建议用户:

  • 在运行npm installyarnnpm ci或等效命令后缓存~/.cache文件夹,如下面的配置所示。

  • 不要在构建之间缓存node_modules。这会绕过npmyarn提供的更智能的缓存,并可能导致Cypress在npm install时不下载Cypress二进制文件的问题。

  • 如果在构建过程中使用npm install,考虑切换到npm ci并缓存~/.npm目录以获得更快更可靠的构建。

  • 如果使用yarn,缓存~/.cache将包括yarn和Cypress缓存。考虑使用yarn install --frozen-lockfile作为npm ci的等效命令。

  • 如果出于某种原因需要覆盖二进制文件位置,使用CYPRESS_CACHE_FOLDER环境变量。

  • 确保没有使用宽松的键恢复先前的缓存;否则Cypress二进制文件可能会"滚雪球"。

**提示:**可以在我们的cypress-example-kitchensink仓库中找到许多配置了缓存的CI示例。

环境变量

可以设置各种环境变量来修改Cypress的运行方式。

配置值

可以将任何配置值设置为环境变量。这会覆盖Cypress配置中的值。

典型用例是修改以下内容:

  • CYPRESS_BASE_URL
  • CYPRESS_VIDEO
  • CYPRESS_VIDEO_COMPRESSION
  • CYPRESS_REPORTER
  • CYPRESS_INSTALL_BINARY

参考环境变量配方获取更多示例。

录制密钥

如果在公共项目上录制运行,需要保护录制密钥。了解原因。

与其像这样硬编码到运行命令中:

cypress run --record --key abc-key-123

可以将录制密钥设置为环境变量CYPRESS_RECORD_KEY,我们会自动使用该值。现在录制时可以省略--key标志。

cypress run --record

通常在CI提供商中设置此值。

CircleCI环境变量

录制密钥环境变量

TravisCI环境变量

Travis密钥环境变量

Git信息

Cypress使用@cypress/commit-info包提取与运行关联的git信息(例如分支、提交消息、作者)。

它假设存在.git文件夹并使用Git命令获取每个属性,如git show -s --pretty=%B获取提交消息,参见src/git-api.js

在某些环境设置下(例如docker/docker-compose),如果.git目录不可用或未挂载,可以通过自定义环境变量传递所有git相关信息。

  • 分支:COMMIT_INFO_BRANCH
  • 消息:COMMIT_INFO_MESSAGE
  • 作者邮箱:COMMIT_INFO_EMAIL
  • 作者:COMMIT_INFO_AUTHOR
  • SHA:COMMIT_INFO_SHA
  • 远程:COMMIT_INFO_REMOTE

如果Cypress Cloud运行中缺少提交信息,GitHub集成或其他任务可能无法正常工作。要查看相关的Cypress调试日志,在CI机器上设置环境变量DEBUG并检查终端输出以了解为什么提交信息不可用。

DEBUG=commit-info,cypress:server:record

CI构建信息

在一些较新的CI提供商中,Cypress无法映射链接回构建或拉取请求所需的环境变量。在这种情况下,我们为用户提供了一些环境变量来帮助传递这些信息。

  • 拉取请求ID:CYPRESS_PULL_REQUEST_ID
  • 拉取请求URL:CYPRESS_PULL_REQUEST_URL
  • 构建URL:CYPRESS_CI_BUILD_URL

设置这些将允许Cloud运行中的链接带你到适当的位置。

自定义环境变量

还可以为测试中使用的自定义环境变量设置动态值。

export "EXTERNAL_API_SERVER=https://corp.acme.co"

然后在测试中:

cy.request({
method: 'POST',
url: Cypress.env('EXTERNAL_API_SERVER') + '/users/1',
body: {
foo: 'bar',
baz: 'quux',
},
})

参考专门的环境变量指南获取更多示例。

模块API

通常,使用Node脚本以编程方式控制和启动服务器可能更简单。

如果使用我们的模块API,可以编写一个启动服务器并在稍后关闭的脚本。作为奖励,可以处理结果并做其他事情。

// scripts/run-cypress-tests.js

const cypress = require('cypress')
const server = require('./lib/my-server')

// 启动服务器
return server.start().then(() => {
// 启动Cypress运行
return cypress.run().then((results) => {
// 完成后停止服务器
return server.stop()
})
})
node scripts/run-cypress-tests.js

常见问题及解决方案

缺少二进制文件

当npm或yarn安装cypress包时,会执行一个postinstall钩子,下载平台特定的Cypress二进制文件。如果钩子因任何原因被跳过,Cypress二进制文件将缺失(除非已经缓存)。

为了更好地诊断错误,在CI设置中添加获取Cypress缓存信息的命令。这将打印二进制文件的位置以及已经存在的版本。

npx cypress cache path
npx cypress cache list

如果缓存中找不到所需的二进制文件版本,可以尝试以下方法:

  1. 使用CI的设置清理缓存,强制在下一次构建时进行干净的npm install
  2. 通过将命令npx cypress install添加到CI脚本中自行安装二进制文件。如果已经存在二进制文件,应该会很快完成。

Xvfb

在Linux上运行时,Cypress需要一个X11服务器;否则它会在测试运行时生成自己的X11服务器。当并行运行多个Cypress实例时,同时生成多个X11服务器可能会导致其中一些出现问题。在这种情况下,可以单独启动一个X11服务器并使用DISPLAY变量将服务器地址传递给每个Cypress实例。

首先,在某个端口(例如:99)后台生成X11服务器。如果在Linux上安装了xvfb或使用cypress-docker-images中的Docker镜像之一,以下工具应该可用。

Xvfb :99 &

其次,在环境变量中设置X11地址

export DISPLAY=:99

照常启动Cypress

npx cypress run

在所有Cypress实例的所有测试完成后,使用pkill终止Xvfb后台进程

pkill Xvfb
caution

在某些Linux环境中,可能会遇到X11服务器的连接错误。在这种情况下,可能需要使用以下命令启动Xvfb:

Xvfb -screen 0 1024x768x24 :99 &

Cypress内部传递这些Xvfb参数,但如果自己生成Xvfb,则需要传递这些参数。这对于避免使用Xvfb的8位色深是必要的,这将防止Chrome或Electron崩溃。

颜色

如果想禁用颜色,可以传递NO_COLOR环境变量。如果ASCII字符或颜色在CI中未正确格式化,可能需要这样做。

NO_COLOR=1 cypress run

另请参阅