使用Cypress进行持续集成
你将学习到
- 如何在持续集成(CI)中设置Cypress
- 如何在CI中运行Cypress、录制测试并并行运行测试
- 如何配置使用Cypress Docker镜像的CI工作流
- 操作系统、依赖项、缓存和环境变量的高级配置
什么是持续集成?
设置CI
基础
在持续集成中运行Cypress与在本地终端运行几乎相同。通常只需要做两件事:
- 安装Cypress
- npm
- yarn
- pnpm
npm install cypress --save-dev
yarn add cypress --dev
pnpm add --save-dev cypress
- 运行Cypress
- npm
- yarn
- pnpm
npx cypress run
yarn cypress run
pnpm 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
大多数CI提供商会自动终止后台进程,因此无需担心在Cypress完成后清理服务器进程。
但如果要在本地运行此脚本,则需要更多工作来收集后台PID并在cypress run
后终止它。
start-server-and-test
模块
如果服务器启动时间非常长,我们建议尝试start-server-and-test模块。
- npm
- yarn
- pnpm
npm install start-server-and-test --save-dev
yarn add start-server-and-test --dev
pnpm add --save-dev start-server-and-test
在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
配置启用时,观看整个测试运行的视频或测试失败时的片段。 - 查看并行化时每台机器运行的测试。
录制测试步骤:
cypress run --record --key=abc123
并行运行测试
Cypress可以在多台机器上并行运行测试。
需要参考CI提供商的文档了解如何在CI环境中设置多台机器。
一旦CI环境中有多台机器可用,可以传递--parallel标志使测试并行运行。
cypress run --record --key=abc123 --parallel
Cypress Docker镜像
CI提供商,如GitHub Actions和CircleCI,允许使用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
镜像,它添加了Chrome、Firefox和Edge浏览器。对于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镜像的示例
- cypress-docker-images示例
- cypress-example-kitchensink。
- Real World App - CircleCI
- Real World App - GitHub Actions
- cypress-docker-images - GitHub Actions
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:
- 录制的视频工件有随机暂停或丢帧。
- CPU和内存的调试日志频繁显示CPU百分比超过100%。
- 浏览器崩溃。
可以通过运行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上运行的机器配置:
- Real World App项目在CircleCI机器上使用Docker执行器和
resource_class: large
运行测试,提供4个vCPU和8GB RAM。cypress info
报告System Memory: 73.6 GB free 48.6 GB
。 - Real World App项目也在GitHub Actions上使用Cypress GitHub Action和公共仓库的标准Ubuntu GitHub托管运行器执行测试,提供4个vCPU和16GB RAM。
cypress info
报告System Memory: 16.8 GB free 15.5 GB
,CPU报告为AMD EPYC 7763 64-Core Processor
。
**提示:**如果较长规格的测试有问题,尝试将它们拆分为较短的规格。
依赖项
Cypress可以在许多CI提供商的虚拟机环境中开箱即用,无需安装额外的依赖项。
Linux
如果在Linux CI环境中运行Cypress时看到缺少依赖项的消息,请参考Linux先决条件列表获取指导。
缓存
Cypress将其二进制文件下载到全局系统缓存——在Linux上是~/.cache/Cypress
。通过确保此缓存在构建之间持久化,可以避免大型二进制文件下载,从而节省安装时间。
我们建议用户:
-
在运行
npm install
、yarn
、npm ci
或等效命令后缓存~/.cache
文件夹,如下面的配置所示。 -
不要在构建之间缓存
node_modules
。这会绕过npm
或yarn
提供的更智能的缓存,并可能导致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环境变量

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
如果缓存中找不到所需的二进制文件版本,可以尝试以下方法:
- 使用CI的设置清理缓存,强制在下一次构建时进行干净的
npm install
。 - 通过将命令
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
- npm
- yarn
- pnpm
npx cypress run
yarn cypress run
pnpm cypress run
在所有Cypress实例的所有测试完成后,使用pkill
终止Xvfb后台进程
pkill Xvfb
在某些Linux环境中,可能会遇到X11服务器的连接错误。在这种情况下,可能需要使用以下命令启动Xvfb:
Xvfb -screen 0 1024x768x24 :99 &
Cypress内部传递这些Xvfb参数,但如果自己生成Xvfb,则需要传递这些参数。这对于避免使用Xvfb的8位色深是必要的,这将防止Chrome或Electron崩溃。
颜色
如果想禁用颜色,可以传递NO_COLOR
环境变量。如果ASCII字符或颜色在CI中未正确格式化,可能需要这样做。
NO_COLOR=1 cypress run
另请参阅
- Cypress Real World App在多个操作系统、浏览器和视口大小上并行运行CI作业。
- cypress-example-kitchensink设置为在多个CI提供商上运行。
- 测试回放
- 跨浏览器测试指南
- 博客:使用适当的npm和Cypress缓存设置Bitbucket Pipelines
- 博客:从任何Docker CI录制测试工件
- 使用Cypress进行持续集成网络研讨会,涵盖TeamCity、Travis和CircleCI设置。