背景
在使用 cypress 做组件测试时遇到一个问题,如何统计组件测试的覆盖率?
根据 cypress 关于覆盖率的介绍,cypress 并不提供这个功能,建议通过 nyc 这个库或通过babel插件 babel-plugin-istanbul 在编译时集成到项目中。
Cypress does not instrument your code - you need to do it yourself. The golden standard for JavaScript code instrumentation is the battle-hardened Istanbul and, luckily, it plays very nicely with the Cypress. You can instrument the code as a build step through one of two ways:
Using the nyc module - a command-line interface for the Istanbul library
As part of your code transpilation pipeline using the babel-plugin-istanbul tool.
其实这两种方式都是基于 Istanbul 实现的, 同时 cypress 提供了一个插件 @cypress/code-coverage 来收集 Istanbul instrument 生成的结果。
对于没有接触过 Istanbul 的我来说,看的有点晕,本文主要是记录下在使用 cypress 对 vue 进行组件测试时,如何进行覆盖率统计。
cypress coverage
进行代码覆盖统计有三步,instrument/collect/report(插桩、收集、展示)。
先给结论:
1、通过 vite-plugin-istanbul 进行 instrument;
2、通过 @cypress/code-coverage 进行收集;
3、通过 nyc 进行数据展示。
下面展开讲一下为什么这么选择和各个方案的实践。
instrument
instrument 的方式挺多的,暂时只对 cypress 推荐的两种方式进行尝试和实现。
1、对完成编译打包的文件进行 instrument,比如使用 nyc 进行 instrument。
// 将 vite 打包后的dist目录拷贝到coverage目录,将新目录打包的js进行 instument(区分测试目录和实际打包目录,这里根据自己需求做就好了)
npm run build // 打包
cp -r ./dist ./coverage // 复制出来做测试
npx nyc instrument ./dist ./coverage // 进行 instrument
执行了 instrument 后可以查看输入目录 coverage 已生成了 instrument 后的代码(后面再聊如何收集)。
2、动态 instrument,使用对应插件进行动态 instrument,比如vite-plugin-istanbul(需要注意区分development/production):
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import istanbul from 'vite-plugin-istanbul';
// https://vitejs.dev/config/
export default defineConfig({
build: {
sourcemap: true
},
plugins: [
vue(),
istanbul({
include: 'src/*',
exclude: ['node_modules'],
extension: ['.js', '.ts', '.vue'],
requireEnv: false,
forceBuildInstrument: false
})
]
})
或者使用babel插件 babel-plugin-istanbul 进行动态instrument,但我目前基本都使用vite来构建项目,暂时不去了解 babel 插件的使用了。
collect
完成了 instrument 后,会在页面其实已生成了 window.coverage 对象,并根据代码执行情况更新覆盖率。
在我项目的组件测试中,cypress 是通过 vite 来启动测试服务的,cypress的配置如下:
// cypress.config.ts
import { defineConfig } from "cypress"
export default defineConfig({
component: {
devServer: {
framework: "vue",
bundler: "vite",
}
}
});
所以我在项目根目录下的 vite.config.ts 配置进行 intrument 即可,然后通过 @cypress/coverage 插件进行 coverage 数据收集:
// cypress.config.ts
import { defineConfig } from "cypress"
import task from '@cypress/code-coverage/task'
export default defineConfig({
component: {
devServer: {
framework: "vue",
bundler: "vite",
},
setupNodeEvents(on, config) {
task(on, config)
// include any other plugin code...
// It's IMPORTANT to return the config object
// with any changed environment variables
return config
}
},
video: false
});
注:如果需要coverage .vue后缀文件,可以通过命令行或者 .nycrc 文件增加 extension 配置,比如:
// .nycrc
{
"extension": [
".js",
".ts",
".vue"
]
}
report
通过 nyc report 命令进行展示,默认是 text 输出,可以在命令行或者配置文件进行配置。
nyc report --reporter=lcov --reporter=text // 输出 text 并在默认 coverage 目录生成html展示文件
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:【文末自行领取】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!