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

加入我们

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

相关推荐
我要洋人死19 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人30 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人31 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR36 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香38 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q24985969341 分钟前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
小牛itbull3 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress