NutUI React 之 PR 自动化测试

NutUI 是一款京东风格的移动端组件库。NutUI 目前支持 Vue 和 React技术栈,支持Taro多端适配。

期待您早日成为我们共建大军中的一员!

官网地址: 点击进入

GitHub地址: 点击进入

欢迎共建、使用!

背景

NUtUI React 在进行从 1.x 到 2.x 的改造升级工作。在这个过程中,每个 PR 都需要进行 Review,除了对代码的规范进行 Review 外,还需要对每个组件的单元测试进行 Review。通常情况下,我们通过在 CI/CD 中跑整体的单元测试来验证组件库的单元测试情况。但在单独组件进行改造的时候,有可能会关联修改其他组件,而没有修改其他组件的单元测试。所以基于这样的情况,我们想优先跑 PR 所修改组件的单元测试。

NutUI React 的 PR 自动化测试主要依赖与 GitHub Actions。所以接下来,我们先看一下 GitHub Actions 的基础使用,然后在深入到 NutUI React 的 PR 自动化测试的实现。

GitHub Actions 介绍

GitHub Actions 是 GitHub 提供的一项功能,可以用来在 GitHub 上创建、测试、部署应用程序。它是一个自动化工作流程平台,可以通过触发事件来执行一系列操作,例如自动化测试,打包构建等。

GitHub Actions 有几个核心的概念:

  1. Workflows(工作流):CI/CD 从开始到结束这个周期可以理解为一个工作流。工作流可以通过 yml 脚本配置,并且一个工作流可以包含一个 Job 或 多个 Job。
  2. Events(事件):触发 Workflows 的特定操作,例如:PR 创建,代码 Push 等。
  3. Jobs(任务):一个 Job 由一系列的步骤组成,其中每个步骤可以标注步骤名称,执行的脚本等。
  4. Actions(动作):每个步骤可以执行的处理,可以是一个或多个。
  5. Runners(执行器):workflows 运行的容器。

上手 GitHub Actions

在仓库中创建 .github/workflows 文件。

.github/workflows 目录中,创建 test.yml,这里只是举例,文件可以定义其他名字。

yaml 复制代码
name: test

on:
  push:
    branches: 
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: echo something
      - run: echo 'Hello World'    

这段代码创建了一个名为 test 的工作流,当对 main 分支进行 push 的时候会触发此工作流的执行。工作流中有一个名为 test 的 Job,运行在 ubuntn 容器中,输出 Hello World。(更多语法可参考这里)

自动化测试实践

单元测试可以分为两种方式处理:通过 Jest 处理全部的单元测试;通过识别变更文件,执行相关组件的单元测试。NutUI React 现在采用的是识别变更文件的方式来处理单元测试。

识别变更文件的方案需要借助 GitHub API 解析出变更文件,之后对变更文件的特征进行处理,识别出组件,执行单元测试。

GitHub 提供了 /repos/{owner}/{repo}/pulls/{pull_number}/files API 用于查询 Pull Request 的相关内容。

要使用此 API ,我们需要提供 owner、repo、pull number 这三个参数的内容。owner、repo 和 pull number 可以通过 GitHub Action 中的上下文来获取:

yml 复制代码
name: CI

on:
  push:
    branches:
      - main

  pull_request:
    branches:
      - main

  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Get PR info
        run: |
          echo "PR Message github.event.number: ${{ github.event.number }}"
          echo "PR Message github.repository: ${{ github.repository }}"

这里给出了一段 GitHub Action 的脚本,在 Get PR info 任务中,借助 linux 的 echo 命令,打印来 github.event.number 和 github.repository。想要对这段脚本进行测试,可将其提交到 .github/workflows/test.yml 中,然后通过其他分支向目标分支创建 PR。(备注:github.event.number来自Webhook 的共有属性

通过执行上述代码,我们可以看到输出的 PR 的 ID 和 repository。接下来要使用他们调用 GitHub 提供的 API。这段代码使用 curl 调用的 GitHub API:

yml 复制代码
pr_number=${{ github.event.number }}
files_url="https://api.github.com/repos/${{ github.repository }}/pulls/$pr_number/files"
files_response=$(curl -sSL -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" $files_url)

这段代码中即有 ${{ xx }} 又有 $xx,我们需要先区分什么时候使用什么形式。${{}} 是 GitHub 提供的插值表达式,在 GitHub Actions 执行的时候会对这种表达式进行求值。$xx 是 Linux shell 的变量调用的方式,在这段 GitHub Actions 中我们实际执行的主要是 Linux shell。

shell 声明变量的方式如下:

shell 复制代码
shellVariable=1

调用变量的方式如下:

shell 复制代码
echo "$shellVariable"

通过 curl 获取到 GitHub API 返回的结果后,需要对结果进行处理,即提取变更文件。

yml 复制代码
files_changed=$(echo "$files_response" | jq -r '.[].filename')
echo "PR files: $files_changed"
component=$(echo "$files_changed" |  grep -E -i 'src\/packages\/([a-z]+)(\/[a-z_\.]*)*' | sed -E 's/src\/packages\/([a-z]+)(\/[a-z_\.]*)*/\1/i' | awk 'END{print}')
npm test -- $component

因为 GitHub API 返回的是 JSON 格式:

shell 复制代码
[
  {
    "sha": "bbcd538c8e72b8c175046e27cc8f907076331401",
    "filename": "src/packages/button/button.tsx",
    "status": "added",
    "additions": 103,
    "deletions": 21,
    "changes": 124,
    "blob_url": "https://github.com/octocat/Hello-World/blob/6dcb09b5b57875f334f61aebed695e2e4193db5e/file1.txt",
    "raw_url": "https://github.com/octocat/Hello-World/raw/6dcb09b5b57875f334f61aebed695e2e4193db5e/file1.txt",
    "contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/file1.txt?ref=6dcb09b5b57875f334f61aebed695e2e4193db5e",
    "patch": "@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"
  }
]

所以我们通过 jq 从 GitHub API 返回的结果中提取我们需要的数据,即第一行代码中的 jq -r '.[].filename,这句代码的意思是取 filename 字段的值,然后以原始文本形式返回。对于上面的 JSON 数据,jq 的处理结果是:src/packages/button/button.tsx。(jq 介绍

获取变更文件后,还需要将src/packages/button/button.tsx中的 button 提取出来,以便传递给 npm 脚本。对于变更文件的处理,主要借助 Linux 中的 grep、sed、awk。

grep -E -i 表示使用正则表达式,并且忽略大小写。 sed -E 同样表示使用正则表达式,但是它的忽略大小写是写到后面的参数中。

到这就完成了 NutUI React PR 自动化测试的 workflow,想要了解上面技术中更多的细节,可以加入我们的咚咚群进行交流。

加入我们

再次期待您早日成为我们共建大军中的一员! 一起共建,一起使用! 做站内最优秀的开源组件库!

相关推荐
前端爆冲10 分钟前
项目中无用export的检测方案
前端
热爱编程的小曾38 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin1 小时前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox1 小时前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞2 小时前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行2 小时前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox