Angular 14项目E2E测试无代码覆盖率问题求助
排查Angular 14 + Playwright + Cucumber + nyc E2E覆盖率无数据问题
1. 先确认代码插桩的核心配置是否适配ESM
Angular 14采用ESM模块规范,nyc配置必须对应调整:
- 确保
nyc.config.js(或.nycrc)里设置"type": "module",明确适配ESM - 配置
include指向需要覆盖的源码路径,比如["src/**/*.ts"],同时用exclude排除测试文件和依赖:["src/**/*.spec.ts", "node_modules/**"] - 开启nyc的ESM支持,添加
"esm": true配置项
2. 检查Playwright+Cucumber的覆盖率收集逻辑
Cucumber的钩子(Hook)里必须明确收集页面的覆盖率数据,否则nyc拿不到原始数据:
import fs from 'fs'; import path from 'path'; import { After } from '@cucumber/cucumber'; After(async function ({ page }) { // 从页面获取插桩生成的覆盖率对象 const coverage = await page.evaluate(() => (window as any).__coverage__); if (!coverage) return; // 将数据写入nyc_output目录 const outputDir = './nyc_output'; if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir); fs.writeFileSync( path.join(outputDir, `coverage-${Date.now()}.json`), JSON.stringify(coverage) ); });
要确保这个After钩子能正常执行,没有被Cucumber的配置忽略。
3. 验证Angular构建时是否注入了插桩代码
默认的ng build不会自动插桩,需要通过webpack配置注入:
- 在
angular.json的build配置里,添加"extraWebpackConfig": "./webpack.coverage.config.js" - 编写
webpack.coverage.config.js(ESM格式):
import { createCoverageTransformer } from '@istanbuljs/load-nyc-config'; const transformer = createCoverageTransformer(); export default { module: { rules: [ { test: /\.ts$/, loader: 'ts-loader', options: { getCustomTransformers: () => ({ before: [transformer] }) }, exclude: /node_modules/ } ] } };
构建时执行ng build --extra-webpack-config webpack.coverage.config.js,之后可以查看dist目录下的JS文件,确认是否包含__coverage__相关的插桩代码。
4. 核对测试执行的完整流程顺序
正确的执行步骤不能乱:
- 清理旧数据:
nyc clean - 构建带插桩的Angular应用:
ng build --configuration=production --extra-webpack-config ... - 启动应用服务(必须用插桩后的构建产物):比如
serve dist/xxx或ng serve(注意ng serve也要用对应的配置) - 运行测试:
nyc cucumber-js
确保测试访问的是插桩后的应用,而非未插桩的开发环境。
5. 排查空覆盖率文件的可能原因
如果nyc_output有文件但内容为空:
- 检查Playwright是否在页面完全加载后再收集覆盖率,异步加载的内容可能导致覆盖率未被捕获
- 确认插桩是否成功:直接在浏览器控制台输入
window.__coverage__,看是否有返回值 - 手动执行
nyc report,强制生成报告,看是否能触发数据合并
内容的提问来源于stack exchange,提问作者DDana
相关产品推荐
相关产品推荐

