SonarQube集成Node.js应用显示代码覆盖率0%如何解决
SonarQube集成Node.js应用覆盖率显示0%的排查修复步骤
按以下顺序逐一排查,绝大多数场景都能定位到根因:
- 第一步先确认覆盖率报告本身有效
先在本地/CI环境执行单测生成覆盖率的命令(比如jest --coverage、nyc npm test),首先确认配置里写的app/coverage/lcov.info文件真实存在,不是0字节空文件。
先打开同目录下的lcov-report/index.html查看本地展示的覆盖率是否非0,如果本地看覆盖率就是0,问题和Sonar无关,先排查单测配置:是不是测试用例根本没命中源码逻辑、是不是把源码全mock了没有真实执行、是不是测试文件匹配规则不对根本没跑到用例。
如果本地html报告覆盖率正常,打开lcov.info查看里面记录的源码路径:很多人遇到0覆盖率是因为lcov里存的是执行环境的绝对路径(比如本地的/Users/xxx/MyApp/app/src/index.js),但Sonar扫描时的项目工作目录路径和这个路径不匹配,Sonar找不到对应被扫描的源码文件,自然不会统计覆盖率。这种情况要么在生成覆盖率时配置输出相对路径(比如jest配置里关闭绝对路径输出,nyc加--exclude-after-remap=false参数),要么在扫描时加sonar.projectBaseDir参数对齐根路径。
另外先核对路径正确性:很多人执行sonar-scanner的目录是项目根目录,但实际coverage文件夹就在根目录下,根本没有app这一层,配置里多写了一层app/前缀,Sonar根本找不到报告文件,自然覆盖率为0。 - 清理无效配置,修正扫描范围
高版本SonarQube(8.0及以上)已经内置lcov解析能力,配置里的sonar.javascript.coveragePlugin=lcov是旧版本遗留配置,留着反而可能触发兼容问题,直接删掉这行即可。
当前配置的sonar.sources=.会把当前目录下所有文件(包括node_modules、测试文件、构建产物)都纳入源码扫描范围,反而会干扰覆盖率匹配。建议明确指定扫描范围:
注意排除规则里不要把存放lcov.info的目录层级写错,不然会把报告文件本身排除掉,Sonar无法读取。# 替换为实际源码目录 sonar.sources=app/src # 替换为实际测试目录 sonar.tests=app/test # 明确排除不需要扫描的目录 sonar.exclusions=app/node_modules/**,app/coverage/**,app/dist/** - 查看扫描日志定位具体报错
执行sonar-scanner时加-X参数开启debug级日志,扫描完成后搜索日志里和coverage、lcov相关的关键词:如果日志出现
No coverage report found for path xxx,就是报告路径配置错误
如果日志出现File xxx is not part of the project, ignoring coverage,就是前文提到的lcov内路径和Sonar扫描的源码路径不匹配
如果日志里完全没有解析lcov文件的相关记录,说明sonar-project.properties文件没被加载——检查这个文件是否放在执行sonar-scanner命令的工作目录下,有没有被Sonar后台的全局配置、CI传入的参数覆盖。 - 特殊场景排查
- 如果用TypeScript开发,要确认生成lcov时开启了source map,保证报告里映射的是.ts源文件而不是编译后的.js文件,不然Sonar匹配不到TS源码会统计为0
- CI环境执行时要确认步骤顺序:必须先执行单测生成lcov.info,再执行sonar-scanner,顺序写反的话扫描时还没生成报告,自然读不到数据
- 如果Sonar后台在项目级/全局级配置了额外的覆盖率排除规则,本地properties文件的配置可能被覆盖,去Sonar项目后台的「配置-排除项」里检查是否把所有源码都排除出了覆盖率统计范围
内容的提问来源于stack exchange,提问作者Aditya
相关产品推荐
相关产品推荐

