2023 年 3 月 24 日

使用 Prisma 进行测试的终极指南:CI 流水线

持续集成 (CI) 是指将来自不同作者的代码更改安全地集成到中央存储库的过程。在本文中,您将更详细地了解 CI 流水线是什么,如何配置 CI 流水线,以及如何使用该流水线来自动化您的测试。

The Ultimate Guide to Testing with Prisma: CI Pipelines

目录

简介

当您来到本系列的结尾时,请退后一步,想想您在过去四篇文章中完成的工作。你

  1. 模拟了 Prisma 客户端
  2. 学习并编写了单元测试
  3. 学习并编写了集成测试
  4. 学习并编写了端到端测试

您学到的测试策略和概念将使您能够编写代码并验证新的更改是否按照您希望和期望的方式与现有代码库一起工作。

这种安心感非常重要,尤其是在大型团队中。然而,您学到的东西中有一个粗糙的边缘:需要在您进行更改时手动运行测试。

在本文中,您将学习如何自动化测试的运行,以便在向主分支发出拉取请求时自动测试对代码库的更改。

什么是持续集成流水线?

持续集成流水线描述了在发布软件新版本之前必须完成的一系列步骤。您可能已经看到或听说过 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 repository button in GitHub

在下一页,系统会要求你提供有关仓库的一些信息。填写下面指示的字段,然后单击页面底部的创建仓库按钮

New repository form in GitHub

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

New repository url in GitHub

现在你有了新 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

你上面添加的步骤执行以下操作

  1. 在虚拟环境中设置 PNPM
  2. 在虚拟环境中设置 Node.js
  3. 在仓库中运行 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 分支中。

在浏览器中前往仓库。在页面顶部的拉取请求选项卡中,你应该看到一个比较和拉取请求按钮,因为 new-branch 最近有推送

GitHub PR tab

单击该按钮以打开拉取请求。你应该被导航到新页面。在新页面上,单击创建拉取请求按钮以打开拉取请求

GitHub create PR page

打开拉取请求后,你应该看到一个黄色框显示在合并拉取请求按钮上方,显示你的Tests 作业正在运行

PR page with unit tests running in a job.

如果你单击详细信息按钮,你应该会看到每个步骤的运行以及其控制台输出。

作业完成后,你将收到通知,告知你的工作流程中的检查是否通过

PR page with successful tests.

现在你的单元测试作业已完成,你将继续创建一个运行集成测试的作业。

注意:请勿合并此拉取请求!你将在本文的其余部分中重复使用此拉取请求。

添加集成测试作业

运行集成测试的过程与运行单元测试的过程非常相似。此作业的不同之处在于,你的集成测试依赖于测试数据库和环境变量。在本节中,你将设置这些内容并定义一个运行测试的作业。

在开始进行更改之前,你需要再次检出仓库的 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 的文件

此操作应执行两项操作

  1. 将 Docker Compose 插件下载到虚拟环境中
  2. 使插件可执行,以便可以使用 docker-compose 命令

将以下内容粘贴到 .github/actions/docker-compose/action.yml 中以处理这些任务

上面的代码片段中的第一步是将 Docker Compose 插件源下载到虚拟环境中的 /usr/local/bin/docker-compose。然后使用 chmod 将此源设置为可执行文件。

自定义操作完成后,将其添加到 .github/workflows/tests.yml 中的 integration-tests 作业中,紧挨着运行测试的步骤之前

此测试需要的最后一件事是一组环境变量。您的应用程序期望的环境变量是

  • DATABASE_URL:数据库的 URL
  • API_SECRET:用于签署 JWT 的身份验证密钥
  • VITE_API_URL:Express API 的 URL

您可以使用 env 关键字将这些添加到虚拟环境中。环境变量可以添加到工作流级别,这会将它们应用于每个作业,也可以添加到特定的作业。在您的情况下,您将它们添加到工作流级别,以便每个作业都可以使用这些变量。

注意:通常的最佳做法是仅向每个作业单独公开所需的环境变量。在本文中,为简单起见,这些变量将公开给每个作业。

env 键添加到您的工作流中,并定义您需要的三个变量

此时,您可以提交并将这些更改推送到 main 分支,以将更改发布到工作流

然后,通过运行以下命令将这些更改合并到 new-branch 分支,以触发工作流的新运行

注意:在 git merge main 步骤中,您将在终端中进入编辑器。按 :qaenter 退出该编辑器。

此作业将比单元测试作业花费更长的时间,因为它必须安装 Docker Compose,启动数据库,然后执行所有测试。

作业完成后,您应该看到以下成功消息

Successfull integration and unit tests.

添加端到端测试作业

现在单元测试和集成测试正在工作流中运行,要定义的最后一组测试是端到端测试。

首先,再次检出 main 分支以更改工作流文件

与上一节的开始方式类似,将 integration-tests 作业的内容复制到一个名为 e2e-tests 的新作业中,将 pnpm backend:tests:int 替换为 pnpm test:e2e

在提交新作业之前,需要做一些事情

  • 在虚拟环境中安装 Playwright 及其测试浏览器
  • 更新 scripts/run-e2e.sh

在此作业中安装 Docker Compose 的步骤之后,添加两个新步骤,将 Playwright 下载并将其测试浏览器安装到项目的 e2e 文件夹中

您还需要在 env 部分中添加两个新的环境变量,Playwright 在安装 Playwright 时将使用这些变量

现在,当工作流运行时,Playwright 应该已安装并正确配置,以允许您的测试运行。

接下来要更改的是 scripts/run-e2e.sh 脚本运行端到端测试的方式。

目前,当端到端测试完成运行时,脚本将自动使用 npx playwright show-report 提供结果报告。在 CI 环境中,您不希望发生这种情况,因为它会导致作业无限期地运行直到手动取消。

从脚本中删除该行

解决了该问题后,您现在可以准备将更改推送到 main,并将这些更改合并到 new-branch 分支

如果您回到浏览器中的拉取请求,您现在应该在检查中看到三个作业正在运行。

新作业将需要很长时间才能完成,因为它必须下载 Docker Compose 和 Playwright 的浏览器,启动数据库并执行所有测试。

作业完成后,您应该看到已完成的成功测试列表

A complete set of successful jobs

总结 & 最终想法

在本文中,您了解了持续集成。更具体地说,您了解了

  • 什么是持续集成
  • 为什么它在您的项目中可能很有用
  • 如何使用 GitHub Actions 设置 CI 管道

最后,您拥有一个 CI 管道,该管道会自动针对与针对 main 分支的拉取请求关联的任何分支运行您的整套测试。

这很强大,因为它允许您在每个拉取请求上设置检查,以确保相关分支中的更改按预期工作。使用 GitHub 的安全设置,您还可以防止在这些检查不成功时合并到 main 中。

在本系列课程中,您了解了可以针对应用程序运行的各种测试类型、如何针对使用 Prisma 与数据库交互的函数和应用程序编写这些测试,以及如何在您的项目中使用这些测试。

如果您对此系列中涵盖的任何内容有任何疑问,请随时在 Twitter 上与我联系。

不要错过下一篇文章!

注册 Prisma 新闻通讯