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,想要了解上面技术中更多的细节,可以加入我们的咚咚群进行交流。

加入我们

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

相关推荐
天宇&嘘月1 小时前
web第三次作业
前端·javascript·css
小王不会写code2 小时前
axios
前端·javascript·axios
发呆的薇薇°3 小时前
vue3 配置@根路径
前端·vue.js
luckyext3 小时前
HBuilderX中,VUE生成随机数字,vue调用随机数函数
前端·javascript·vue.js·微信小程序·小程序
小小码农(找工作版)3 小时前
JavaScript 前端面试 4(作用域链、this)
前端·javascript·面试
前端没钱4 小时前
前端需要学习 Docker 吗?
前端·学习·docker
前端郭德纲4 小时前
前端自动化部署的极简方案
运维·前端·自动化
海绵宝宝_4 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
码农土豆5 小时前
chrome V3插件开发,调用 chrome.action.setIcon,提示路径找不到
前端·chrome
鱼樱前端5 小时前
深入JavaScript引擎与模块加载机制:从V8原理到模块化实战
前端·javascript