品质保证:发布覆盖率测试报告

Posted 天界程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了品质保证:发布覆盖率测试报告相关的知识,希望对你有一定的参考价值。

代码覆盖率才是评价一个项目品质的标准。在挑选一个项目的时候,有经验的使用者都会根据代码覆盖率来确定代码的可靠性。

虽然自动化测试工具可以自动验证代码的正确性,但是如果只有部分代码经过了测试,或者只是简单地跑通了代码,也不能说是一个合格的代码。比如组件库只测试一部分的组件,或者每个组件只测试了默认设置。譬如,按钮中某个属性或者某几个属性间的排列组合并没有得到测试,这样的测试还不能保证组件库的功能完全正确。

那么如何来客观评价这个测试的完备程度呢?答案就是代码覆盖率。


javascript 是前端应用主要语言,相较于其他平台编程语言,JS资源多数情况下要通过网络进行加载,那么代码的体积直接影响了页面加载执行时间。“无效的代码”的多寡直接影响到了我们的代码质量,所以度量代码的执行覆盖率是一项重要的优化前置工作。

Dead code

Dead code 也叫无用代码,这个概念应是在编译时静态分析出的对执行无影响的代码,举个例子:

// a.js
const a = 1;
const b = 2; /* dead code */
export default a;

// index.js
import a from './a.js';
export default function() 
  console.log(a);

通常我们用 Tree Shaking 在编译时移除这些 dead code以减小代码体积。


冗余代码

而代码覆盖率里所提到的冗余代码 和 Dead Code 又略有不同,简单来说Dead code适用于编译时,而 Code coverage 适用于运行时。

Dead code 是任何情况下都不会执行的代码,所以可以再编译阶段将其剔除。

冗余代码 是某些特定的业务逻辑之下并不会执行到这些代码逻辑(比如:在首屏加载时,某个前端组件完全不会加载,那么对于“首屏”这个业务逻辑用例来讲,该前端代码就是冗余的)。


覆盖率概念

代码覆盖率(Code coverage)是软件测试中的一种度量指标,描述测试过程中(运行时)被执行的源代码占全部源代码的比例。

只是简单地做到行级覆盖还远远不够,可以看看下面的例子

function getStr(a, b) 
    if(a && b) 
        return 'both'
    else 
        return 'other'
    

以上代码只需要两个 Case,就可以将所有语句都跑一遍:

  • Case 01: a = true ; b = true; 期待结果:‘both’
  • Case 02: a =false ; b= true; 期待结果:‘other’

但是,显然这样测试甚至不能确定代码中 b 是否参与条件判断。比如下面代码可能也会出现相同的结果。

function getStr(a, b) 
    if( a ) 
        return 'both'
    else 
        return 'other'
    

所以覆盖率只有简单的代码行覆盖还远远不够。


覆盖率种类

在软件工程理论中会把覆盖率分为:

  • 语句覆盖(statement coverage)
  • 判定覆盖(decision coverage)
  • 条件覆盖(condition coverage)
  • 条件判定组合覆盖(condition decision coverage)
  • 路径覆盖(path coverage)
  • 多条件覆盖(multi-condition coverage)
  • 修正条件判定覆盖(modified condition / decision coverage)

覆盖深度的提高显然会让代码功能验证更加全面,但是相应的实施成本也会明显提高。

理论的覆盖虽然全面但是实际生产很多指标的指导价值并不是很大。在实际生产中会将它进行简化。

在 Javascript 语言中,代码覆盖率通常会分为四级覆盖。

  • Function coverage 函数覆盖 - 每个函数是否被执行;
  • Line coverage 行覆盖 – 每行是否被执行;
  • Statement coverage 语句覆盖 - 每个语句是否被执行;
  • Branch coverage 分支覆盖 - 每个 if 节点是否都被执行。

这是结合了函数式语言的特点和指标的实用程度的经验之谈,也是 JavaScript 世界比较受认可的标准。


Istanbul 代码覆盖率工具

代码覆盖率需要专用的工具生成。在 JavaScript 程序中的代码覆盖率通常都是通过 Istanbul 生成的。Istanbul 的来历是伊斯坦布尔的地毯,覆盖率报告其实就是用颜色来表示代码的运行情况,好像给代码铺上了地毯。

我们熟悉的 Jest 和组件库使用的 Vitest 测试框架,都是使用的 Istanbul。Istanbul 的实现原理是通过编译期代码插桩方式实现的。有兴趣的同学可以研究一下。咱们这里面只讲如何使用。

覆盖率原理介绍:http://www.alloyteam.com


生成覆盖率报告

在 Vitest 只需要在命令行中添加参数 --coverage 就可以生成覆盖率报告了。

文件名:package.json

"scripts": 
    "coverage": "vitest run --coverage"
  ,

还需要安装依赖@vitest/coverage-c8

pnpm i @vitest/coverage-c8 -D

执行命令

pnpm coverage

执行完命令后会生成一个coverage目录,且控制台有相应结果

浏览器查看coverage目录的index.html

默认报告形式是一个静态网站。

如果想对报告进行进一步调整,可以在 vite.config.ts 中进行。

test: 
    coverage: 
      provider: "istanbul", // or 'c8',
      reporter: ["text", "json", "html"],
    ,
  ,

调整的两项是:

  • 指定覆盖率引擎 istanbul;
  • 指定输出格式,默认是没有 json 格式的。这个和后面的覆盖率展示有关,务必要加。

安装依赖

pnpm i @vitest/coverage-istanbul -D

执行命令

pnpm coverage


公布覆盖率报告

覆盖率报告放在本地只能给自己的单元测试提供依据,更大的用途在于将覆盖率报告公布展示出来,让使用者可以看到。通常会选用覆盖率展示平台,常用的有 Codecov 和 Coveralls。

Codecov 是一个开源的测试结果展示平台,将测试结果可视化。Github 上许多开源项目都使用了 Codecov 来展示单测结果。Codecov 跟 Travis CI 一样都支持 Github 账号登录,同样会同步 Github 中的项目。

还会自动的生成徽章。这个徽章是会根据报告结果动态变化的,属于客观的第三方数据,具有公信力。

首先需要登录Codecov 官网:https://about.codecov.io/

一定要使用 Github 账号进行登录,这样它可以直接读取你的 Github 中的项目。

然后是添加访问授权,如果你的项目在你名下的组织下,也需要访问授权

这时候你就可以在网站上找到所有 Github 中的项目。选择 【Not yet setup 】,选择需要展示覆盖率报告的网站后的【 setup repo】链接,就可以看到安装指南。

它这个安装指南是针对所有语言项目的。这里面我们只需要得到它的上传 Token 就好了。


持续集成自动更新覆盖率报告

覆盖率报告最好能够自动按照最新版本持续更新,而不是自己手动上传。所以这个时候就需要使用 CI 工具来帮忙了。首先需要编写一个 Action。

文件名:.github/wokflows/codecov.yml

# .github/workflows/main.yml
# This is a basic workflow to help you get started with Actions

name: Coverage

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  CodeCov:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      - uses: actions/checkout@v2
      - uses: pnpm/action-setup@v2.1.0
        with:
          version: 7.2.1
      - name: Install modules
        run: pnpm install
      - name: Run Test Coverage
        run: cd packages/smarty-ui-vite && pnpm coverage
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          directory: packages/smarty-ui-vite/coverage
          token: $ secrets.CODECOV_TOKEN 

上传报告环节同样使用现成的 Action 。这里面需要添加 Token,把上面 codecov 安装指南中得到的 Token 放入 Secrets 中。

提交代码就可以自动生成覆盖率报告了。

Codecov Action 会自动识别语言与测试框架的覆盖率报告种类,然后上传相应的数据。这里面要特别说明,对于 Vitest ,是上传的 json 格式的报告,所以需要确定你确实生成了 json 报告。如何生成可以看上文介绍。


添加覆盖率徽章

最后就是富有仪式感的一步。Codecov 网站可以将测试结果生成为徽章。你可以把徽章直接放到 Github 中展示出来。

在项目的【 Settings 】中找到对应的徽章。

覆盖率报告是项目品质的重要指标,成熟的项目都会把项目展示在显眼的位置,大家通常都会拿代码覆盖率指标评价开源代码的成熟度。当然过高的覆盖率也会带来成本的提高,和拉低项目进步速率。

品质、进度、成本是每一个项目管理中都需要均衡的东西。所以一味追求代码覆盖率也未必是好事。这个大家要客观看待。

以上是关于品质保证:发布覆盖率测试报告的主要内容,如果未能解决你的问题,请参考以下文章

带有 python 测试的 Vue Cypress 代码覆盖率报告

使用命令行 android studio 运行 testSuite 并生成代码覆盖率报告

伊斯坦布尔覆盖与 mocha 测试用例仅显示规范文件(测试文件)的覆盖率报告

如何在 vs 代码中使用 mocha 生成覆盖率报告?

徒手搭建Python单元测试框架

如何使用 angular9 和 Jasmine 为所有组件生成 .pdf 格式的单元测试用例代码覆盖率报告