用于前端测试的测试管道 101
已发表: 2022-03-10想象一下这种情况:您正在快速接近最后期限,并且您正在利用每一分钟来实现完成这个复杂重构的目标,并在您的 CSS 文件中进行大量更改。 您甚至可以在乘坐公共汽车期间完成最后的步骤。 但是,您的本地测试似乎每次都失败,并且您无法让它们正常工作。 你的压力水平正在上升。
在某知名剧集中确实有类似的场景:出自Netflix的电视剧《如何在网上卖药(快速)》第三季:
Cypress + Vue 出现在*NETFLIX 电视节目中*
— 杰斯 (@_jessicasachs) 2021 年 8 月 7 日
这是一部名为“如何卖药(快)”的喜剧,它对 webdev 有一些最真实的描述。
第 3 季,第 1 集 @ 20:20 和之前的一两次。 pic.twitter.com/ICSAwMxyFB
好吧,你可能会想,他至少在使用测试。 你可能想知道,为什么他仍然处于困境中? 即使您编写测试,仍有很大的改进空间和避免这种情况。 您如何看待从一开始就监控您的代码库和所有更改? 这样一来,您就不会遇到如此令人讨厌的惊喜了,对吧? 包含这样的自动化测试例程并不难:让我们从头到尾一起创建这个测试管道。
我们走吧!
首先要做的事情:基本术语
构建例程可以帮助您对更复杂的重构保持信心,即使在您的小型副项目中也是如此。 但是,这并不意味着您需要成为 DevOps 工程师。 学习一些术语和策略很重要,这就是你来这里的目的,对吧? 幸运的是,您来对地方了! 让我们从处理前端项目的测试管道时很快会遇到的基本术语开始。
如果你用谷歌搜索整个测试世界,你可能已经偶然发现“CI/CD”这个术语是第一个术语之一。 它是“Continuous Integration、Continuous Delivery”和“Continuous Deployment”的缩写,准确地描述为:您可能已经听说过,它是开发团队用来更频繁、更可靠地部署代码更改的一种软件分发方法。 CI/CD 涉及两种互补的方法,它们在很大程度上依赖于自动化。
- 持续集成
这是自动化措施的一个术语,用于实现小的、常规的代码更改并将它们合并到共享存储库中。 持续集成包括构建和测试代码的步骤。
CD 是“Continuous Delivery”和“Continuous Deployment”的首字母缩写词,这两个概念彼此相似,但有时在不同的上下文中使用。 两者的区别在于自动化的范围:
- 持续交付
它指的是之前已经测试过的代码过程,运营团队现在可以将它们部署到实时生产环境中。 这最后一步可能是手动的。 - 持续部署
顾名思义,它侧重于“部署”方面。 这是一个术语,用于开发人员更改从存储库到生产的全自动发布过程,客户可以直接使用它们。
这些流程旨在使开发人员和团队能够拥有一个产品,如果他们愿意,您可以随时发布该产品: 对持续监控、测试和部署的应用程序充满信心。
为了实现精心设计的 CI/CD 策略,大多数人和组织都使用称为“管道”的流程。 “管道”是我们在本指南中已经使用的一个词,没有解释它。 如果您考虑这样的管道,那么将管道作为长途线路来运输天然气等东西并不是太牵强。 DevOps 领域的管道功能非常相似:它们正在“传输”要部署的软件。
等等,这听起来需要学习和记住很多东西,对吧? 我们不是讨论过测试吗? 你是对的:涵盖 CI/CD 管道的完整概念将为多篇文章提供足够的内容,我们希望为小型前端项目提供测试管道。 或者您只是缺少管道的测试方面,因此只专注于持续集成过程。 因此,我们将特别关注管道的“测试”部分。 因此,我们将在本指南中创建一个“小型”测试管道。
好的,所以“测试部分”是我们的主要关注点。 在这种情况下,您已经知道哪些测试并第一眼就浮现在您的脑海中? 如果我以这种方式考虑测试,这些是我自发想到的测试类型:
- 单元测试是一种测试,其中应用程序的次要可测试部分或单元(称为单元)被单独和独立地测试以确保正确运行。
- 集成测试关注组件或系统之间的交互。 这种测试意味着我们正在检查单元的相互作用以及它们如何协同工作。
- 端到端测试,或 E2E 测试,意味着实际的用户交互由计算机模拟; 为此,E2E 测试应包括应用程序中使用的尽可能多的功能区域和技术堆栈部分。
- 可视化测试是检查应用程序的可见输出并将其与预期结果进行比较的过程。 换句话说,它有助于在页面或屏幕的外观中发现与纯粹功能性错误不同的“视觉错误”。
- 静态分析并不是精确的测试,但我认为这里有必要提一下。 你可以想象它像拼写更正一样工作:它在不运行程序的情况下调试你的代码并检测代码样式问题。 这个简单的措施可以防止许多错误。
为了有信心在我们独特的项目中合并大规模重构,我们应该考虑在我们的测试管道中使用所有这些测试类型。 但是先入为主会很快导致挫败感:评估这些测试类型时您可能会感到迷茫。 我应该从哪里开始? 哪些类型的测试有多少是合理的?
战略:金字塔和奖杯
在开始构建我们的管道之前,我们需要制定测试策略。 之前搜索所有这些问题的答案,您可能会在一些隐喻中找到可能的解决方案:在网络和测试社区中,人们倾向于使用类比来让您了解应该使用哪种类型的测试。
您可能会遇到的第一个比喻是测试自动化金字塔。 Mike Cohn 在他的著作《Succeeding with Agile》中提出了这个概念,Martin Fowler 将其进一步发展为“实际测试金字塔”。 它看起来像这样:
如您所见,它由三个级别组成,对应于所呈现的三个测试级别。 金字塔旨在阐明不同测试的正确组合,以指导您制定测试策略:
- 单元
您可以在金字塔的基础层找到这些测试,因为它们执行速度快且易于维护。 这是由于它们的孤立以及它们针对最小单位的事实。 有关测试非常小的产品的典型单元测试示例,请参阅此示例。 - 一体化
这些处于金字塔的中间,因为它们在执行速度方面仍然可以接受,但仍然让您有信心比单元测试更接近用户。 集成类型测试的一个例子是 API 测试,组件测试也可以被认为是这种类型。 - E2E 测试(也称为UI 测试)
正如我们所看到的,这些测试模拟了真正的用户及其交互。 这些测试需要更多时间来执行,因此成本更高——被放置在金字塔的顶部。 如果您想查看 E2E 测试的典型示例,请查看此示例。
然而,近年来,这种比喻感觉已经过时了。 特别是它的一个缺陷对我来说至关重要:在这个策略中,静态分析被绕过了。 在我看来,这个比喻没有考虑使用代码风格的修复程序或其他 linting 解决方案,这是一个巨大的缺陷。 Lint 和其他静态分析工具是使用中管道的一个组成部分,不容忽视。
所以,让我们简而言之:我们应该使用更新的策略。 但是缺少 linting 工具并不是唯一的缺陷——还有一个更重要的问题需要考虑。 相反,我们可能会稍微转移注意力:以下引用总结得很好:
“写测试。 不是很多。 主要是整合。”
— 吉列尔莫·劳赫
让我们分解这句话来了解它:
- 编写测试
不言自明——你应该总是写测试。 测试对于在您的应用程序中灌输信任至关重要——对于用户和开发人员都是如此。 甚至为自己! - 不是很多
随意编写测试不会让你有任何收获; 测试金字塔在其声明中仍然有效,以保持测试优先。 - 主要是集成
金字塔忽略的更“昂贵”测试的一张王牌是,随着您向上移动金字塔,对测试的信心就会增加。 这种增加意味着作为开发人员的用户和您自己最有可能信任这些测试。
这意味着我们应该按照设计进行更接近用户的测试。 结果,您可能会支付更多费用,但您会获得很多回报。 您可能想知道为什么不选择 E2E 测试? 因为他们在模仿用户,他们不是最接近用户的吗? 确实如此,但它们的执行速度仍然慢得多,并且需要完整的应用程序堆栈。 因此,这种投资回报比集成测试更晚实现:因此,集成测试在一方面的信任与另一方面的速度和努力之间提供了公平的平衡。
如果您关注 Kent C.Dodds,这些论点对您来说可能听起来很熟悉,尤其是当您特别阅读他的这篇文章时。 这些论点并非巧合:他在工作中提出了一个新策略。 我非常同意他的观点,并将此处最重要的观点和资源部分中的其他观点联系起来。 他建议的方法源于测试金字塔,但通过改变其形状以反映集成测试的更高优先级,将其提升到另一个层次。 它被称为“测试奖杯”。
测试奖杯是一个隐喻,以稍微不同的方式描述测试的粒度; 您应该将测试分配到以下测试类型:
- 静态分析在这个比喻中起着至关重要的作用。 这样,您只需运行提到的调试步骤即可发现拼写错误、类型错误和其他错误。
- 单元测试应确保您的最小单元得到适当的测试,但测试奖杯不会像测试金字塔那样强调它们。
- 集成是主要关注点,因为它是平衡成本和提高置信度的最佳方式。
- UI 测试,包括 E2E 和视觉测试,位于测试奖杯的顶端,类似于它们在测试金字塔中的作用。
我在大多数项目中都采用了这种测试奖杯策略,我将在本指南中继续这样做。 但是,我需要在这里给出一点免责声明:当然,我的选择是基于我在日常生活中所做的项目。 因此,匹配测试策略的好处和选择始终取决于您正在处理的项目。 所以,如果它不符合您的需求,请不要难过,我会在相应段落中为其他策略添加资源。
轻微剧透警告:在某种程度上,我也需要稍微偏离这个概念,你很快就会看到。 但是,我认为这很好,但我们稍后会讨论。 我的观点是在规划和实施管道之前考虑测试类型的优先级和分布。
如何在线构建这些管道(快速)
Netflix 的电视剧《如何在网上卖药(快速)》第三季中的主角在接近截止日期时使用 Cypress 进行 E2E 测试,然而,这实际上只是本地测试。 没有看到 CI/CD,这给他带来了不必要的压力。 我们应该用我们学到的理论来避免给定的主角在相应的情节中的压力。 但是,我们如何将这些知识应用到现实中呢?
首先,我们需要一个代码库作为测试基础。 理想情况下,它应该是我们许多前端开发人员都会遇到的项目。 它的用例应该是一个常见的用例,非常适合动手方法,并使我们能够从头开始实施测试管道。 这样的项目会是什么?
我对主管道的建议
我想到的第一件事是不言而喻的:我的网站,即我的投资组合页面,非常适合被视为示例代码库,由我们有抱负的管道进行测试。 它在 Github 上开源,因此您可以自由查看和使用它。 关于该网站的技术栈的几句话:基本上,我在 Vue.js 上构建了这个网站(不幸的是,当我写这篇文章时,它仍然是第 2 版)作为一个 JavaScript 框架,而 Nuxt.js 作为一个额外的 Web 框架。 您可以在其 GitHub 存储库中找到完整的实现示例。
选择我们的示例代码库后,我们应该开始应用我们的学习。 鉴于我们希望使用测试奖杯作为我们测试策略的起点,我提出了以下概念:
由于我们正在处理一个相对较小的代码库,我将合并单元测试和集成测试的各个部分。 然而,这只是这样做的一小部分原因。 其他更重要的原因是:
- 单元的定义通常是“有待讨论的”:如果你让一群开发人员定义一个单元,你会得到各种各样的、不同的答案。 正如一些人提到的功能、类或服务——次要单元——另一个开发人员将计入完整的组件。
- 除了那些定义上的困难之外,在单元和集成之间划一条线可能很棘手,因为它非常模糊。 这种斗争是真实的,尤其是对于前端,因为我们经常需要 DOM 来成功验证测试基础。
- 通常可以使用相同的工具和库来编写两个集成测试。 因此,我们也许可以通过合并它们来节省资源。
首选工具:GitHub Actions
我们知道我们想要在管道中描绘什么,接下来是选择持续集成和交付 (CI/CD) 平台。 在为我们的项目选择这样的平台时,我会考虑我已经获得的经验:
- GitLab,在我工作场所的日常工作中,
- 我的大多数辅助项目中的 GitHub Actions。
但是,还有许多其他平台可供选择。 考虑到所使用的技术和框架,我建议您始终根据您的项目及其特定要求进行选择——这样就不会出现兼容性问题。 请记住,我们使用了一个已经在 GitHub 上发布的 Vue 2 项目,恰好符合我之前的经验。 另外,上面提到的 GitHub Actions 只需要你项目的 GitHub 仓库作为起点即可; 专门为其创建和运行 GitHub Actions 工作流。 因此,我将在本指南中使用 GitHub Actions。
因此,如果发生某些给定事件,这些 GitHub 操作为您提供了一个运行专门定义的工作流的平台。 这些事件是我们存储库中触发工作流的特定活动,例如,将更改推送到分支。 在本指南中,这些事件与 CI/CD 相关联,但此类工作流程也可以自动化其他工作流程,例如为拉取请求添加标签。 GitHub 可以在 Windows、Linux 和 macOS 虚拟机上执行它们。
为了可视化这样的工作流程,它看起来像这样:
在本文中,我将使用一个工作流程来描绘一个管道; 这意味着一个工作流程将包含我们所有的测试步骤,从静态分析到各种 UI 测试。 该管道,或在以下段落中称为“工作流”,将由一个甚至多个作业组成,这些作业是在同一个运行器上执行的一组步骤。
这个工作流程正是我想在上图中绘制的结构。 在其中,我们仔细研究了这样一个包含多个工作的跑步者; 作业本身的步骤由不同的步骤组成。 这些步骤可以是以下两种类型之一:
- 一个步骤可以运行一个简单的脚本。
- 一个步骤可以运行一个动作。 此类操作是可重用的扩展,通常是完整的自定义应用程序。
记住这一点,GitHub 操作的实际工作流程如下所示:
编写我们的第一个 GitHub Action
最后,我们可以编写自己的第一个 Github 动作并编写一些代码! 我们将从我们的基本工作流程和我们想要描述的工作的第一个大纲开始。 记住我们的测试奖杯,每项工作都将类似于测试奖杯中的一层。 这些步骤将是我们需要做的事情来自动化这些层。
因此,我首先创建.github/workflows/
目录来存储我们的工作流。 我们将创建一个名为tests.yml
的新文件,以在此目录中包含我们的测试工作流程。 除了上图中看到的标准工作流语法外,我将继续进行如下操作:
- 我将把我们的工作流程命名为
Tests CI
。 - 因为我想在每次推送到远程分支时执行我的工作流并提供手动选项来启动我的管道,所以我将配置我的工作流以在
push
和workflow_dispatch
上运行。 - 最后但同样重要的是,如“我对基本管道的建议”段落所述,我的工作流程将包含三个工作:
-
static-eslint
用于静态分析; -
unit-integration-jest
用于将单元和集成测试合并到一项工作中; -
ui-cypress
作为 UI 阶段,包括基本的 E2E 测试和视觉回归测试。
-
- 基于 Linux 的虚拟机应该执行所有作业,所以我将使用
ubuntu-latest
。
输入正确的YAML
文件语法,我们工作流程的第一个大纲可能如下所示:
name: Tests CI on: [push, workflow_dispatch] # On push and manual jobs: static-eslint: runs-on: ubuntu-latest steps: # 1 steps unit-integration-jest: runs-on: ubuntu-latest steps: # 1 step ui-cypress: runs-on: ubuntu-latest steps: # 2 steps: e2e and visual
如果您想深入了解 GitHub 操作中的工作流程的详细信息,请随时访问其文档。 无论哪种方式,您无疑都知道这些步骤仍然缺失。 别担心——我也知道。 因此,要使这个工作流程大纲充满活力,我们需要定义这些步骤并决定将哪些测试工具和框架用于我们的小型投资组合项目。 所有接下来的段落都将描述各自的工作,并包含使所述测试的自动化成为可能的几个步骤。
静态分析
正如测试奖杯所暗示的,我们将从工作流程中的 linter 和其他代码风格的修复程序开始。 在这种情况下,您可以从许多工具中进行选择,其中一些示例包括:
- Eslint 作为 Javascript 代码样式修复器。
- 用于 CSS 代码修复的 Stylelint。
- 我们可以考虑更进一步,例如,要分析代码复杂性,您可以查看像审查器这样的工具。
这些工具的共同点是它们指出了模式和约定中的错误。 但是,请注意,其中一些规则是个人喜好问题。 由您决定执行它们的严格程度。 举个例子,如果您要容忍两个或四个制表符的缩进。 更重要的是专注于要求一致的代码风格和捕捉更关键的错误原因,例如使用“==”与“===”。
对于我们的投资组合项目和本指南,我想开始安装 Eslint,因为我们使用了大量的 Javascript。 我将使用以下命令安装它:
npm install eslint --save-dev
当然,如果我不想使用 NPM,我也可以使用 Yarn 包管理器的替代命令。 安装后,我需要创建一个名为.eslintrc.json
的配置文件。 现在让我们使用基本配置,因为本文不会首先教您如何配置 Eslint:
{ "extends": [ "eslint:recommended", ] }
如果您想详细了解 Eslint 配置,请参阅本指南。 接下来,我们要做第一步来自动化 Eslint 的执行。 首先,我想将命令设置为将 Eslint 作为 NPM 脚本执行。 我通过在script
部分的package.json
文件中使用此命令来实现此目的:
"scripts": { "lint": "eslint --ext .js .", },
然后我可以在我们的 GitHub 工作流程中执行这个新创建的脚本。 但是,在这样做之前,我们需要确保我们的项目可用。 因此,我们使用预配置的 GitHub Action actions/checkout@v2
来执行此操作:签出我们的项目,以便您的 GitHub 操作的工作流程可以访问它。 下一步是安装我的投资组合项目所需的所有 NPM 依赖项。 在那之后,我们终于准备好运行我们的 eslint 脚本了! 我们使用 linting 的最后一项工作现在看起来像这样:
static-eslint: runs-on: ubuntu-latest steps: # Action to check out my codebase - uses: actions/checkout@v2 # install NPM dependencies - run: npm install # Run lint script - run: npm run lint
你现在可能想知道:当我们的npm run lint
时,这个管道会自动“失败”吗? 是的,这确实是开箱即用的。 一旦我们完成了工作流程的编写,我们将在 Github 上查看屏幕截图。
单元与集成
接下来,我想创建包含单元和集成步骤的作业。 关于本文使用的框架,我想给大家介绍一下用于前端测试的 Jest 框架。 当然,如果您不想使用 Jest,则无需使用 - 有许多替代方案可供选择:
- 赛普拉斯还提供非常适合集成测试的组件测试。
- Jasmine 也是另一个值得研究的框架。
- 还有更多; 我只是想列举几个。
Jest 由 Facebook 开源提供。 该框架归功于其对简单性的关注,同时与许多 JavaScript 框架和项目兼容,包括 Vue.js、React 或 Angular。 我还可以将 jest 与 TypeScript 结合使用。 这使得该框架非常有趣,特别是对于我的小型投资组合项目,因为它兼容且非常适合。
我们可以通过输入以下命令直接从我的投资组合项目的这个根文件夹开始安装 Jest:
npm install --save-dev jest
安装后,我已经可以开始编写测试了。 但是,本文重点介绍使用 Github 操作自动化这些测试。 因此,要了解如何编写单元或集成测试,请参阅以下指南。 在我们的工作流程中设置作业时,我们可以与static-eslint
作业类似地进行。 所以,第一步是再次创建一个小的 NPM 脚本,以便稍后在我们的工作中使用:
"scripts": { "test": "jest", },
之后,我们将定义名为unit-integration-jest
的工作,类似于我们之前为 linter 所做的工作。 因此,工作流程将检查我们的项目。 除此之外,我们将使用与我们的第一个static-eslint
作业的两个细微差别:
- 我们将使用一个操作作为安装 Node.js 的步骤。
- 之后,我们将使用我们新创建的 npm 脚本来运行我们的 Jest 测试。
这样,我们的unit-integration-jest
工作将如下所示:
unit-integration-jest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Set up node - name: Run jest uses: actions/setup-node@v1 with: node-version: '12' - run: npm install # Run jest script - run: npm test
UI 测试:E2E 和可视化测试
最后但同样重要的是,我们将编写我们的ui-cypress
Job,其中将包含 E2E 测试和视觉测试。 将这两者结合在一项工作中很聪明,因为我将同时使用 Cypress 框架。 当然,您可以考虑其他框架,例如下面的 NightwatchJS 和 CodeceptJS。
同样,我们将仅介绍在 GitHub 工作流程中进行设置的基础知识。 如果你想详细了解如何编写 Cypress 测试,我的另一本指南正好解决了这个问题。 本文将指导您完成定义 E2E 测试步骤所需的一切。 好的,首先我们将安装 Cypress,就像我们安装其他框架一样,在我们的根文件夹中使用以下命令:
npm install --save-dev cypress
这一次,我们不需要定义 NPM 脚本。 赛普拉斯已经为我们提供了自己的 GitHub 操作cypress-io/github-action@v2
。 在那里,我们只需要配置一些东西来让它运行:
- 我们需要确保我们的应用程序已完全设置并正常工作,因为 E2E 测试需要完整的应用程序堆栈可用。
- 我们需要命名我们在其中运行 E2E 测试的浏览器。
- 我们需要等待网络服务器完全运行,这样计算机才能像真正的用户一样工作。
幸运的是,我们的 Cypress 操作帮助我们使用with
区域存储所有这些配置。 这样,我们当前的 GitHub 作业看起来是这样的:
steps: - name: Checkout uses: actions/checkout@v2 # Install NPM dependencies, cache them correctly # and run all Cypress tests - name: Cypress Run uses: cypress-io/github-action@v2 with: browser: chrome headless: true # Setup: Nuxt-specific things build: npm run generate start: npm run start wait-on: 'http://localhost:3000'
视觉测试:为您的测试提供一些关注
记住我们编写本指南的初衷:我对 SCSS 文件进行了大量更改,进行了重大重构——我想在构建例程中添加测试,以确保不会破坏其他任何内容。 有了静态分析、单元、集成和端到端测试,我们应该很有信心,对吧? 没错,但我仍然可以做一些事情来使我的管道更加防弹和完美。 你可以说它正在变成奶精。 尤其是在处理 CSS 重构时,E2E 测试只能提供有限的帮助,因为它只能通过在测试中写下来完成您所说的事情。
幸运的是,除了书面命令之外,还有另一种捕获错误的方法,因此,除了概念之外。 这叫做视觉测试:你可以把这种测试想象成一个找不同的谜题。 从技术上讲,可视化测试是一种屏幕截图比较,它将截取您的应用程序的屏幕截图并将其与现状进行比较,例如,来自项目的主分支。 这样一来,任何意外的样式问题都不会被忽视——至少在您使用可视化测试的领域是这样。 至少在我的经验中,这可以将可视化测试变成大型 CSS 重构的救星。
有许多可视化测试工具可供选择,值得一看:
- Percy.io,我在本指南中使用的 Browserstack 工具;
- 如果您不想使用 SaaS 解决方案并同时完全开源,则可以使用 Visual Regression Tracker;
- 具有 AI 支持的 Applitools。 在 Smashing 杂志上有一个关于这个工具的令人兴奋的指南;
- 彩色故事书。
对于本指南以及基本上对于我的投资组合项目,重用我现有的赛普拉斯测试进行可视化测试至关重要。 如前所述,由于集成简单,我将在此示例中使用 Percy。 虽然它是一个 SaaS 解决方案,但仍然有很多部分是开源的,并且有一个免费计划,对于许多开源或其他副项目来说应该足够了。 但是,如果您觉得在使用开源工具的同时完全自托管更自在,您可以试试 Visual Regression Tracker。
本指南将只为您提供 Percy 的简要概述,否则将为全新文章提供内容。 但是,我会为您提供帮助您入门的信息。 如果您现在想深入了解细节,我建议您查看 Percy 的文档。 那么,我们怎样才能让我们的测试眼睛,可以这么说呢? 假设我们现在已经编写了一两个 Cypress 测试。 想象它们看起来像这样:
it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); });
当然,如果我们想安装 Percy 作为我们的可视化测试解决方案,我们可以使用 cypress 插件来实现。 所以,就像我们今天做了几次一样,我们使用 NPM 将它安装在我们的根文件夹中:
npm install --save-dev @percy/cli @percy/cypress
之后,您只需要将percy/cypress
包导入到您的cypress/support/index.js
索引文件中:
import '@percy/cypress';
此导入将使您能够使用 Percy 的快照命令,该命令将从您的应用程序中获取快照。 在这种情况下,快照是指从您可以配置的不同视口或浏览器截取的一组屏幕截图。
it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); // Take a snapshot cy.percySnapshot('Home page'); });
回到我们的工作流程文件,我想将 Percy 测试定义为工作的第二步。 在其中,我们将运行脚本npx percy exec -- cypress run
与 Percy 一起运行我们的测试。 要将我们的测试和结果连接到我们的 Percy 项目,我们需要传递我们的 Percy 令牌,该令牌被 GitHub 机密隐藏。
steps: # Before: Checkout, NPM, and E2E steps - name: Percy Test run: npx percy exec -- cypress run env: PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
为什么我需要 Percy 令牌? 这是因为 Percy 是用于维护我们的屏幕截图的 SaaS 解决方案。 它将保留屏幕截图和现状以供比较,并为我们提供屏幕截图审批工作流程。 在那里,您可以批准或拒绝任何即将发生的更改:
查看我们的作品:GitHub 集成
恭喜! 我们成功地构建了我们的第一个 GitHub 操作工作流。 让我们最后看一下我的投资组合页面存储库中的完整工作流程文件。 你不好奇它在实际使用中的样子吗? 您可以在存储库的“操作”选项卡中找到您正在使用的 GitHub 操作:
在那里,您可以找到与您的工作流文件等效的所有工作流。 如果您查看一个工作流程,例如我的“Tests CI”工作流程,您可以检查它的所有工作:
如果您想查看您的一项工作,您也可以在边栏中选择它。 在那里,您可以检查您的工作日志:
你看,如果错误发生在你的管道中,你就能够检测到它们。 顺便说一句,“操作”选项卡不是您可以检查 GitHub 操作结果的唯一地方。 您也可以在拉取请求中检查它们:
I like to configure those GitHub actions the way they need to be executed successfully: Otherwise, it's not possible to merge any pull requests into my repository.
结论
CI/CD helps us perform even major refactorings — and dramatically minimizes the risk of running into nasty surprises. The testing part of CI/CD is taking care of our codebase being continuously tested and monitored. Consequently, we will notice errors very early, ideally before anyone merges them into your main branch. Plus, we will not get into the predicament of correcting our local tests on the way to work — or even worse — actual errors in our application. I think that's a great perspective, right?
To include this testing build routine, you don't need to be a full DevOps engineer: With the help of some testing frameworks and GitHub actions, you're able to implement these for your side projects as well. I hope I could give you a short kick-off and got you on the right track.
I'm looking forward to seeing more testing pipelines and GitHub action workflows out there! ️
资源
- An excellent guide on CI/CD by GitHub
- “The practical test pyramid”, Ham Vocke
- Articles on the testing trophy worth reading, by Kent C.Dodds:
- “Write tests. 不是很多。 Mostly integration”
- “The Testing Trophy and Testing Classifications”
- “Static vs Unit vs Integration vs E2E Testing for Frontend Apps”
- I referred to some examples of the Cypress real world app
- Documentation of used tools and frameworks:
- GitHub actions
- Eslint docs
- 笑话文档
- 赛普拉斯文档
- Percy documentation