持续集成 (CI) 是指将来自不同作者的代码更改安全地集成到中央存储库的过程。在本文中,您将更详细地了解 CI 管道是什么、如何配置 CI 管道以及如何使用该管道来自动化您的测试。
目录
介绍
当您来到本系列的结尾时,请回顾一下并思考一下您在前四篇文章中完成了什么。您
- 模拟了 Prisma 客户端
- 学习并编写了单元测试
- 学习并编写了集成测试
- 学习并编写了端到端测试
您学习到的测试策略和概念将使您能够编写代码,并验证新更改在现有代码库中是否如您所希望和期望的那样工作。
这种安心感非常重要,尤其是在大型团队中。然而,您所学到的知识中存在一个不足之处:需要在您进行更改时手动运行测试。
在本文中,您将学习如何自动化测试的运行,以便在向主分支发出拉取请求时,对代码库的更改将自动进行测试。
什么是持续集成管道?
持续集成管道描述了在发布新版本的软件之前必须完成的一系列步骤。您可能已经看到或听说过 CI/CD 这个缩写,它指的是持续集成以及持续部署。通常,这些单独的概念是通过管道来处理的,就像您今天将看到的那样。
就本文而言,您将主要关注 CI 部分,您将在其中构建、测试并最终合并您的代码。
有许多技术可以让您设置管道,选择使用哪种技术通常取决于您使用的技术栈。例如,您可以在以下工具中设置管道:
- Jenkins
- CircleCI
- GitLab
- AWS Codepipeline
- 等等...
在本文中,您将学习如何使用 GitHub Actions 定义您的管道,这将允许您在每次向主分支创建拉取请求时,将您的管道配置为针对代码更改运行。
您将使用的技术
先决条件
假设的知识
在完成以下步骤时,拥有以下知识将很有帮助
- Git 的基本使用知识
- Docker 的基本理解
开发环境
要跟随提供的示例进行操作,您需要拥有
本系列大量使用这个 GitHub 仓库。请确保克隆该仓库。
克隆仓库
在您的终端中,前往您存储项目的目录。在该目录中运行以下命令
上面的命令会将项目克隆到一个名为 testing_mono_repo
的文件夹中。该仓库的默认分支是 main
。
您需要切换到 e2e-tests
分支,该分支包含来自上一篇文章的完整端到端测试设置
一旦您克隆了仓库并检出了正确的分支,就需要执行几个步骤来设置项目。
首先,安装 node_modules
接下来,在项目根目录创建一个 .env
文件
将以下变量添加到新文件中
在 .env
文件中,添加了以下变量
API_SECRET
:提供身份验证服务用于加密密码的密钥。在实际应用中,此值应替换为包含数字和字母字符的长随机字符串。DATABASE_URL
:包含数据库的 URL。VITE_API_URL
:Express API 的 URL 位置。
设置您自己的 GitHub 仓库
为了开始配置在 GitHub Actions 中运行的管道,您首先需要您自己的 GitHub 仓库,其中包含一个 main
分支,用于提交拉取请求。
前往 GitHub 网站并登录您的帐户。
注意:如果您还没有 GitHub 帐户,可以在此处创建一个免费帐户。
登录后,单击下面指示的 New 按钮以创建一个新仓库

在下一页,您将被要求提供有关您的仓库的一些信息。填写下面指示的字段,然后点击页面底部的 Create repository 按钮

然后您将被导航到新仓库的主页。顶部会有一个文本字段,您可以在其中复制仓库的 URL。单击复制图标以复制 URL

现在您已经有了新 GitHub 仓库的 URL,请在终端中进入代码库的根目录,并使用以下命令更改项目的origin 以指向新仓库(请务必在第二行插入您刚刚复制的 URL)
您将基于 e2e-tests
分支的进度进行工作,因此该分支应被视为 main
。将 e2e-tests
合并到 main
最后,将项目推送到您的新仓库
设置工作流程
您现在已经设置了一个可以推送更改的仓库。下一个目标是在每次针对您已创建的 main
分支进行或更新拉取请求时,触发一组任务。
使用 GitHub 时,您可以创建工作流程文件来定义这些步骤。这些文件必须在项目根目录中的 .github/workflows
文件夹中创建。
在您的项目中创建一个名为 .github
的新文件夹
在 .github/workflows
文件夹中,创建一个新文件,您将在其中定义您的测试工作流程,命名为 test.yml
在此文件中,您将提供 GitHub Actions 应采取的步骤来准备您的项目并运行您的测试套件。
要开始此工作流程,请使用 name
属性为您的工作流程命名
现在,该工作流程将在 GitHub 中显示为 'Tests'
。
下一步是配置此工作流程,使其仅在针对仓库的 main
分支发出拉取请求时运行。添加带有以下选项的 on
关键字以完成此操作
注意:请注意缩进。缩进在 YAML 文件中非常重要,不正确的缩进会导致文件失败。
现在您已经命名了您的工作流程,并将其配置为仅在针对 main
进行或更新拉取请求时运行。接下来,您将开始定义一个运行单元测试的任务。
注意:工作流程文件中有很多选项可以配置,这些选项会更改工作流程的运行方式、功能等等……有关完整列表,请查看 GitHub 的文档。
添加单元测试任务
要在工作流程中定义一组与特定任务(称为步骤)相关的指令,您将使用 job
关键字。每个任务都在您配置的隔离环境中运行其步骤集。
将 jobs
部分添加到 .github/workflows/tests.yml
文件,并指定一个名为 unit-tests
的任务
如前所述,每个单独的任务都在其自己的环境中运行。为了运行一个任务,您需要指定该任务应在哪种类型的机器中运行。
使用 runs-on
关键字指定该任务应在 ubuntu-latest
机器上运行
您将定义的最后一个部分是 steps
部分,用于设置您的单元测试任务,您将在其中定义任务应采取的一组步骤来运行您的单元测试。
将以下内容添加到 unit-tests
任务
这定义了一个包含一个步骤的 steps
部分。该步骤使用名为 actions/checkout
的预构建操作的 v3 版本,该操作检出您的 GitHub 仓库,以便您可以在任务内部与之交互。
注意:操作 是您可以在工作流程中使用的一组单独的步骤。它们可以帮助将可重用的步骤集分解为单个文件。
接下来,您需要定义一组步骤,这些步骤将在虚拟环境中安装 Node.js,安装 PNPM,并安装您的仓库的软件包。
您创建的每个测试任务都需要这些步骤,因此您将在可重用的自定义操作中定义这些步骤。
在 .github
目录中创建一个名为 actions
的新文件夹,并在 .github/actions
文件夹中创建一个 build
文件夹
然后在 .github/actions/build
中创建一个名为 action.yml
的文件
在该文件中,粘贴以下内容
此文件定义了一个复合操作,它允许您在任务中使用此操作中定义的 steps
。
您上面添加的步骤执行以下操作
- 在虚拟环境中设置 PNPM
- 在虚拟环境中设置 Node.js
- 在仓库中运行
pnpm install
以安装node_modules
现在已经定义了这个可重用的操作,您可以在您的主工作流程文件中使用它。
返回 .github/workflows/tests.yml
,使用 uses
关键字来使用该自定义操作
此时,该任务将检出仓库,设置虚拟环境并安装 node_modules
。剩下的就是实际运行测试。
添加最后一个步骤,该步骤运行 pnpm test:backend:unit
以运行单元测试
注意:请注意,您使用
name
关键字将此新步骤命名为'Run tests'
,并使用run
关键字运行了任意命令。
此任务现已完成,可以进行测试。为了进行测试,请首先将此代码推送到您仓库的 main
分支
现在,工作流程在 main
分支上定义。但是,仅当您针对该分支提交拉取请求时,才会触发工作流程。
创建一个名为 new-branch
的新分支
在该新分支中,通过向 backend/src/index.ts
文件添加注释来进行小的更改
现在提交并将这些更改推送到远程仓库。仓库目前不知道 new-branch
分支,因此您需要指定 origin 应使用名为 new-branch
的分支来处理这些更改
新分支现在在远程仓库上可用。创建一个拉取请求以将此分支合并到 main
分支。
前往浏览器中的仓库。在页面顶部的 Pull requests 选项卡中,您应该看到 Compare & pull request 按钮,因为 new-branch
最近有推送

单击该按钮以打开拉取请求。您应该被导航到一个新页面。在该新页面上,单击 Create pull request 按钮以打开拉取请求

打开拉取请求后,您应该在 Merge pull request 按钮上方看到一个黄色框,显示您的 Tests 任务正在运行

如果您单击 Details 按钮,您应该看到每个步骤都在运行及其控制台输出。
一旦任务完成,您将收到通知,告知您的工作流程中的检查是否通过

现在您的单元测试任务已完成,您将继续创建运行集成测试的任务。
注意:暂时不要合并此拉取请求!您将在本文的其余部分重复使用此拉取请求。
添加集成测试任务
运行集成测试的过程与运行单元测试的过程非常相似。此任务的不同之处在于,您的集成测试依赖于测试数据库和环境变量。在本节中,您将设置这些内容并定义一个运行测试的任务。
在开始进行更改之前,您需要再次检出仓库的 main
分支
首先将 unit-tests
任务复制到一个名为 integration-tests
的新任务中。此外,在此任务的最后一步中,将 pnpm test:backend:unit
替换为 pnpm test:backend:int
有了这个,您已经拥有了运行测试所需的大部分组件,但是按原样运行工作流程将触发 scripts/run-integration.sh
文件的运行。该脚本使用 Docker Compose 启动测试数据库。
GitHub Actions 使用的虚拟环境默认不附带 Docker Compose。为了使其工作,您将设置另一个自定义操作,将 Docker Compose 安装到环境中。
在 .github/actions
中创建一个名为 docker-compose
的新文件夹,并在其中创建一个名为 action.yml
的文件
此操作应执行两件事
- 将 Docker Compose 插件下载到虚拟环境中
- 使插件可执行,以便可以使用
docker-compose
命令
将以下内容粘贴到 .github/actions/docker-compose/action.yml
中以处理这些任务
上面代码片段中的第一步将 Docker Compose 插件源下载到虚拟环境中的 /usr/local/bin/docker-compose
中。然后它使用 chmod
将此源设置为可执行文件。
自定义操作完成后,在 .github/workflows/tests.yml
中的 integration-tests
任务中,在运行测试的步骤之前添加它
此测试需要的最后一件事是一组环境变量。您的应用程序期望的环境变量是
DATABASE_URL
:数据库的 URLAPI_SECRET
:用于签署 JWT 的身份验证密钥VITE_API_URL
:Express API 的 URL
您可以使用 env
关键字将这些添加到虚拟环境中。环境变量可以在工作流程级别添加,这将它们应用于每个任务,也可以应用于特定任务。在您的情况下,您将在工作流程级别添加它们,以便变量在每个任务中都可用。
注意:通常的最佳实践是仅将所需的环境变量单独暴露给每个任务。在本文中,为了简单起见,变量将暴露给每个任务。
将 env
键添加到您的工作流程,并定义您需要的三个变量
此时,您可以提交并将这些更改推送到 main
分支,以发布对工作流程的更改
然后通过运行以下命令将这些更改合并到 new-branch
分支中,以触发工作流程的新运行
注意:在
git merge main
步骤中,您将进入终端中的编辑器。按:qa
和enter
键退出该编辑器。
此任务将比单元测试任务花费更长的时间,因为它必须安装 Docker Compose、启动数据库,然后执行所有测试。
一旦任务完成,您应该看到以下成功消息

添加端到端测试任务
现在单元测试和集成测试都在工作流程中运行,要定义的最后一组测试是端到端测试。
首先,再次检出 main
分支以更改工作流程文件
与上一节的开始方式类似,将 integration-tests
任务的内容复制到一个名为 e2e-tests
的新任务中,将 pnpm backend:tests:int
替换为 pnpm test:e2e
在提交新任务之前,有几件事要做
- 在虚拟环境中安装 Playwright 及其测试浏览器
- 更新
scripts/run-e2e.sh
在此任务中安装 Docker Compose 的步骤之后,添加两个新步骤,在项目的 e2e
文件夹中下载 Playwright 并安装其测试浏览器
您还需要向 env
部分添加两个新的环境变量,Playwright 在安装 Playwright 时将使用这些变量
现在,当工作流程运行时,Playwright 应该已正确安装和配置,以允许您的测试运行。
接下来要更改的是 scripts/run-e2e.sh
脚本运行端到端测试的方式。
目前,当端到端测试运行完成后,脚本将使用 npx playwright show-report
自动提供结果报告。在 CI 环境中,您不希望发生这种情况,因为它会导致任务无限期运行,直到手动取消。
从脚本中删除该行
解决了这个问题后,您现在可以推送您的更改到 main
并将这些更改合并到 new-branch
分支中
如果您回到浏览器中的拉取请求,您现在应该在检查中看到三个任务正在运行。
新任务将花费很长时间才能完成,因为它必须下载 Docker Compose 和 Playwright 的浏览器,启动数据库并执行所有测试。
一旦任务完成,您应该看到已完成的成功测试列表

总结与最终思考
在本文中,您学习了有关持续集成的知识。更具体地说,您学习了
- 什么是持续集成
- 为什么它在您的项目中很有用
- 如何使用 GitHub Actions 设置 CI 管道
最后,您拥有了一个 CI 管道,该管道针对与针对 main
分支的拉取请求关联的任何分支自动运行您的整个测试套件。
这非常强大,因为它允许您在每个拉取请求上设置检查,以确保相关分支中的更改按预期工作。使用 GitHub 的安全设置,您还可以防止在这些检查不成功时合并到 main
分支。
在本系列的课程中,您学习了所有关于您可以针对应用程序运行的各种测试类型,如何针对使用 Prisma 与数据库交互的函数和应用程序编写这些测试,以及如何在您的项目中使用这些测试。
如果您对本系列中涵盖的任何内容有任何疑问,请随时通过 Twitter 与我联系。
不要错过下一篇文章!
注册 Prisma 新闻邮件