作业需求
生成前端项目代码覆盖率报告
测试环境
- Win11
- Angular 17 (typescript)
- VUE、React 项目也可以使用,已测试通过,步骤一样
试验工具
- nyc
-
istanbul-middleware
原理
使用 nyc 对代码进行插庄,然后运行插庄后的代码,将覆盖率信息(window.__coverage__ 变量)提交给 istanbul-middleware 中间件,由 istanbul-middleware 将覆盖率信息进行可视化,比如 html 格式
试验过程
1. 安装 istanbul-middleware,搭建中间件服务。相关接口参考下方链接
如果需要自定义服务,请参考 istanbul-middleware - npm (npmjs.com)
npm i istanbul-middleware
const express = require('express')
const istanbulMiddleware = require('istanbul-middleware')
const app = express()
app.use(istanbulMiddleware.createHandler())
app.get('/helloworld', function (req, res) {
res.send('Hello World')
})
app.listen(8888)
2. 安装 nyc
npm i -D nyc
3. 对代码进行插桩
nyc instrument <input_dir> <output_dir>
3.1、 使用以下工具可以对 TS 项目在编译时进行插桩,这是 nyc 官方给推荐的工具。JS 项目用
babel-plugin-istanbul,请参考 github 或者 npm 对该库的使用介绍,注意与TS插件的使用方式不同。
npm i @istanbuljs/nyc-config-typescript
3.2、在项目根目录下新建 .nycrc 配置文件,或者在 package.json 中添加一个 "nyc":{} 项
内容如下
{
"extends": "@istanbuljs/nyc-config-typescript",
"all": true,
"check-coverage": true,
"report-dir": "coverage",
"include": [
"src/**/*.ts"
],
"exclude": [
"**/*.spec.ts"
],
"reporter": [
"lcov",
"text"
],
"extension": [
".ts"
],
"cache": true,
"temp-dir": ".nyc_output"
}
4. 运行程序获取覆盖率
ng serve
打开浏览器控制台,如果有 window.__coverage__ 变量,说明已经运行成功
5. 访问 istanbul-middleware 查看覆盖率信息
curl /show?p=<window.__coverage__.path>&v=<custom_version:option>
注意事项
- nyc 不能利用插庄代码单独生成覆盖率信息,它需要借助其他测试工具才能获取覆盖率信息,nyc 是一个覆盖率收集工具
- 如果想使用 nyc 命令来生成覆盖率信息,似乎是需要写测试代码的,并不能既要使用nyc对代码进行插桩,又使用nyc对插桩的代码生成其他可视化格式的覆盖率信息。(个人理解,这里我发现了一个悖论、nyc report --reporter=html 生成其他格式覆盖率信息时,会对当前代码进行类是于插桩的标记,在 .nyc_output 文件夹下可以看到。但是如果使用 nyc instrument 对代码进行插桩后,插桩的代码就被写入了文件内,这时候再时候前者生成html就会对已插桩的代码进行标记,可以理解为进行了两次插庄,一次是在代码中可以看到的,一次是看不到的。所以生成的覆盖率一定是错误的)
- 如果组件报错,需要以下配置
'use strict'; const { parserPlugins } = require('@istanbuljs/schema').defaults.nyc; module.exports = { cache: false, parserPlugins: parserPlugins.concat('typescript', 'jsx','decorators-legacy') };