Angular 13多入口库项目代码覆盖率收集与聚合方案咨询
我刚好在Angular 13的多入口库项目中解决过几乎一模一样的问题,给你分享两个经过验证的实现方案,既能高效收集覆盖率,又能自动聚合报告:
方案1:自定义脚本+Istanbul手动聚合
这个方案不需要额外引入第三方工具,仅通过修改Angular配置+Node脚本就能实现批量测试和覆盖率聚合:
步骤1:修改angular.json测试配置
在主项目的test架构中,配置覆盖率报告输出为JSON格式,并为每个入口点生成独立的覆盖率文件:
{ "projects": { "your-main-lib": { "architect": { "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "projects/your-main-lib/src/test.ts", "tsConfig": "projects/your-main-lib/tsconfig.spec.json", "karmaConfig": "projects/your-main-lib/karma.conf.js", "codeCoverage": true, "codeCoverageExclude": [], "watch": false } } } } } }
步骤2:动态配置Karma覆盖率文件名
修改projects/your-main-lib/karma.conf.js,通过环境变量识别当前测试的入口点,生成带标识的覆盖率文件:
module.exports = function (config) { const entryPoint = process.env.ENTRY_POINT || 'unknown'; config.set({ // 保留原有配置... coverageReporter: { reporters: [ { type: 'json', dir: './coverage/raw', file: `coverage-${entryPoint}.json` } ] } }); };
步骤3:编写批量测试与聚合脚本
在项目根目录创建scripts/aggregate-coverage.js脚本,批量执行每个入口点的测试,再用Istanbul工具聚合所有覆盖率数据:
const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); const { createReporter } = require('istanbul-reports'); const { ReportAggregator } = require('istanbul-lib-report'); const { createContext } = require('istanbul-lib-report'); const { loadCoverage } = require('istanbul-lib-coverage'); // 替换为你的41个入口点列表,也可以从angular.json自动读取 const entryPoints = ['entry-module-1', 'entry-module-2', 'entry-module-3']; // 批量执行每个入口点的测试 entryPoints.forEach(entry => { console.log(`=== 开始测试入口点: ${entry} ===`); execSync( `ENTRY_POINT=${entry} ng test your-main-lib --configuration production`, { stdio: 'inherit' } ); }); // 聚合所有覆盖率文件 const rawCoverageDir = path.join(__dirname, '../coverage/raw'); const coverageFiles = fs.readdirSync(rawCoverageDir).filter(f => f.endsWith('.json')); const coverageMap = {}; coverageFiles.forEach(file => { const content = fs.readFileSync(path.join(rawCoverageDir, file), 'utf8'); Object.assign(coverageMap, JSON.parse(content)); }); // 生成聚合后的覆盖率报告(HTML、Lcov、JSON格式) const globalCoverage = loadCoverage(coverageMap); const context = createContext({ dir: path.join(__dirname, '../coverage/aggregated') }); const aggregator = new ReportAggregator({ coverageMap: globalCoverage }); const reporters = [ createReporter('html', { dir: 'html' }), createReporter('lcovonly', { file: 'lcov.info' }), createReporter('json', { file: 'coverage-final.json' }) ]; reporters.forEach(reporter => { reporter.onStart(context); aggregator.visit(reporter); reporter.onEnd(); }); console.log('=== 聚合覆盖率报告已生成在 coverage/aggregated ===');
步骤4:添加npm脚本
在package.json中添加快捷执行命令:
{ "scripts": { "test:coverage": "node scripts/aggregate-coverage.js" } }
方案2:利用Nx简化多项目测试与覆盖率聚合
如果可以引入Nx工具,它对Angular多项目工作区的测试和覆盖率聚合支持非常友好,还自带缓存机制能大幅缩短重复测试的时间:
- 安装Nx:
npm install nx --save-dev
- 直接执行批量测试并生成聚合覆盖率:
nx run-many --target=test --projects=your-main-lib-* --codeCoverage --parallel
--parallel参数可以同时执行多个入口点的测试,--codeCoverage会自动生成聚合后的覆盖率报告在coverage目录下,而且Nx会缓存已测试过的模块,后续重复执行时只会跑修改过的代码。
额外优化技巧
- 开启Angular CLI缓存:在
angular.json根节点添加"cli": {"cache": {"enabled": true}},复用之前的构建结果,减少每个入口点的测试耗时。 - 并行执行测试:在方案1的脚本中改用
child_process.spawn或concurrently工具,同时运行多个入口点的测试,进一步缩短总时间。 - 排除无关文件:在
codeCoverageExclude中配置不需要统计覆盖率的文件(如测试文件、第三方依赖),减少计算量。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

