通过Jenkins执行时SonarQube代码覆盖率报告显示待覆盖行数为零的问题排查
我之前也踩过Jenkins+SonarQube覆盖率为空的坑,结合你的场景来看,大概率是测试报告的路径匹配问题——本地和Jenkins的工作目录上下文不一样,导致SonarQube找不到生成的覆盖率和测试报告。下面一步步拆解问题和解决办法:
核心原因推测
你的本地操作正常,但Jenkins里出问题,核心差异在于:
- 相对路径不匹配:SonarQube配置的
sonar.cs.opencover.reportsPaths=Tests/**/coverage.opencover.xml是相对sonarscanner begin执行的目录(也就是Jenkins里的SberSpace目录),但Jenkins中dotnet test生成的报告可能不在这个路径下。 - 报告生成位置不确定:默认情况下,dotnet test在解决方案根目录执行时,会把报告生成在测试项目自己的目录下(比如
Tests/YourTestProject/coverage.opencover.xml),如果你的测试项目结构和Tests/**/的匹配逻辑有偏差,Sonar就会找不到文件。 - 引号转义潜在问题:虽然你的Jenkinsfile里对logger参数做了转义,但某些环境下可能存在引号处理异常,导致测试报告没正确生成。
分步解决方案
1. 先确认报告是否生成、在哪生成
在Jenkinsfile中添加调试步骤,查看报告的实际位置:
dir("SberSpace"){ // ... 保留之前的sonar begin和build命令 exec "dotnet test --logger \"trx;LogFileName=TestResults.trx\" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover" // 添加这行,查看报告文件的实际路径 exec "find . -name 'coverage.opencover.xml' -o -name 'TestResults.trx'" // ... 后续sonar end命令 }
执行Jenkins任务后,看控制台输出,确认这两个文件的路径是否和Sonar配置的Tests/**/匹配。
2. 强制指定报告生成路径
修改dotnet test命令,明确把报告生成到Sonar能识别的路径下:
exec "dotnet test --logger \"trx;LogFileName=Tests/TestResults.trx\" /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=Tests/"
这里通过/p:CoverletOutput=Tests/把覆盖率文件强制生成到SberSpace/Tests目录,同时把trx报告也指定到该目录,确保Sonar的Tests/**/路径能准确匹配到。
3. 放宽Sonar的报告路径匹配规则
如果你的测试项目结构不统一,可以把Sonar的报告路径改成更通用的匹配,覆盖所有子目录:
def SonarBeginCommand = """${sonarExec} begin /d:sonar.login=${SonarUser} /d:sonar.password=${SonarPass} /d:sonar.host.url=https://sbt-sonarqube.sigma.sbrf.ru /k:SBERSPACE:backend /n:SBERSPACE:backend \ /d:sonar.branch.name=feature/TEAMX-3687-xunit-sonar \ /d:sonar.cs.opencover.reportsPaths=**/coverage.opencover.xml \ /d:sonar.cs.vstest.reportsPaths=**/TestResults.trx \ /d:sonar.sourceEncoding=UTF-8"""
**/会匹配当前目录下的所有子目录,确保Sonar能找到任何位置的报告文件。
4. 确认Jenkins工作目录正确性
检查dir("SberSpace")是否确实指向了你的.NET解决方案根目录(也就是包含.sln文件的目录),可以添加以下命令验证:
dir("SberSpace"){ exec "pwd" // 查看当前工作目录 exec "ls -la" // 查看目录下的文件,确认有.sln文件 }
如果路径不对,所有相对路径都会失效。
5. 查看SonarScanner的执行日志
在Jenkins控制台输出中,找到SonarScanner end阶段的日志,看看是否有类似提示:
No coverage reports found using the pattern Tests/**/coverage.opencover.xml
如果有,就实锤是路径匹配问题,按照上面的步骤调整即可。
内容的提问来源于stack exchange,提问作者vitaly

