17370845950

解决 SonarQube 中 JaCoCo 代码覆盖率显示为 0% 的问题

本文旨在解决 Maven 项目在 SonarQube 中代码覆盖率显示为 0% 的常见问题。核心原因通常是 JaCoCo 和 Surefire 插件配置不一致,导致 JaCoCo 覆盖率数据文件未正确生成或 SonarQube 无法找到生成的 XML 报告。我们将详细指导如何正确配置 pom.xml 和 Jenkins Pipeline,确保 JaCoCo 数据生成、XML 报告输出以及 SonarQube 正确读取。

1. 问题背景与根源分析

当您在 Jenkins Pipeline 中为 Spring Boot 应用执行 JUnit 测试并通过 SonarQube 进行代码质量分析时,可能会遇到 SonarQube 中代码覆盖率始终显示为 0% 的情况。这通常伴随着 JaCoCo 插件在构建日志中发出类似 Skipping JaCoCo execution due to missing execution data file 的警告。

此问题的根本原因在于 JaCoCo Maven 插件、Maven Surefire 插件以及 SonarQube 配置之间存在不一致。具体来说,主要有以下几点:

  • JaCoCo .exec 数据文件未生成或路径错误: JaCoCo 通过在 JVM 启动时注入代理来收集代码覆盖率数据,并将数据写入 .exec 文件。如果 Surefire 插件(负责运行测试)未能正确集成 JaCoCo 代理,或 .exec 文件生成路径与后续报告生成或 SonarQube 查找的路径不符,就会导致数据丢失。
  • JaCoCo XML 报告未生成或路径错误: SonarQube 通常需要 JaCoCo 生成的 XML 格式报告来导入覆盖率数据。如果 JaCoCo 报告生成阶段未正确配置,或者生成的 XML 报告路径与 SonarQube 配置中指定的路径不一致,SonarQube 将无法找到并解析覆盖率数据。
  • SonarQube 参数配置不正确: 在 Jenkins Pipeline 中调用 mvn sonar:sonar 命令时,传递给 SonarQube 的 JaCoCo 报告路径参数可能与实际生成的报告路径不匹配,或者使用了错误的参数名称。

为了解决这些问题,我们需要确保 JaCoCo、Surefire 和 SonarQube 之间的配置保持高度一致性。

2. Maven pom.xml 配置详解

pom.xml 是配置 JaCoCo 和 Surefire 插件的关键。以下是推荐的配置方式,确保 JaCoCo 代理正确注入测试 JVM,并生成 SonarQube 可识别的 XML 报告。

2.1 项目属性定义

块中,定义 JaCoCo .exec 文件和 XML 报告的路径,以及 Surefire 报告的路径。这将有助于保持配置的一致性。


    1.8
    UTF-8

    
    ${project.build.directory}/jacoco.exec
    
    ${project.build.directory}/jacoco_report

    
    ${project.build.directory}/surefire-reports
    ${jacoco.report.dir}/jacoco.xml

2.2 Maven Surefire 插件配置

Surefire 插件负责运行单元测试。它需要使用 JaCoCo 代理来收集覆盖率数据。这通过 配置实现,该配置会从 JaCoCo 的 prepare-agent 目标中获取 JVM 参数。


    
        
        
            org.apache.maven.plugins
            maven-surefire-plugin
            2.22.2 
            
                
                ${surefireArgLine}
                
                ${sonar.surefire.reportsPath}
            
        
        
    

2.3 JaCoCo Maven 插件配置

JaCoCo 插件有两个主要目标需要配置:prepare-agent 和 report。

  • prepare-agent:在测试运行之前准备 JaCoCo 代理,并将其配置为 Surefire 插件的 。
  • report:在测试运行之后,根据 .exec 文件生成可供 SonarQube 使用的 XML 格式报告。

    
        

        
        
            org.jacoco
            jacoco-maven-plugin
            0.8.6 
            
                
                
                    prepare-agent
                    
                        prepare-agent
                    
                    
                        
                        ${jacoco.exec.file}
                        
                        surefireArgLine
                    
                
                
                
                    report
                    post-unit-test 
                    
                        report
                    
                    
                        
                        ${jacoco.exec.file}
                        
                        ${jacoco.report.dir}
                        
                        
                            XML
                        
                    
                
            
        
    

3. Jenkins Pipeline 配置示例

在 Jenkins Pipeline 中,您需要执行 Maven 命令来构建、测试并触发 SonarQube 分析。关键在于确保 mvn sonar:sonar 命令能够正确地找到 JaCoCo 生成的 XML 报告。

pipeline {
    agent any
    stages {
        stage('Build and Test') {
            steps {
                script {
                    // 清理、编译、运行测试并生成 JaCoCo .exec 数据和 XML 报告。
                    // 'verify' 阶段会包含 'test' 阶段和 'post-unit-test' 阶段(JaCoCo report 目标绑定在此)。
                    // 确保所有测试都运行,并且 JaCoCo 报告被生成。
                    sh 'mvn clean verify'
                }
            }
        }
        stage('SonarQube Analysis') {
            steps {
                script {
                    // 确保此处的报告路径与 pom.xml 中 JaCoCo 插件实际生成 XML 报告的路径一致。
                    // 对应 pom.xml 中  的值
                    def jacocoXmlReportPath = "target/jacoco_report/jacoco.xml"

                    sh "mvn sonar:sonar " +
                       "-Dsonar.projectKey=your_project_key " + // 替换为您的 SonarQube 项目 Key
                       "-Dsonar.sources=src/main/java " +
                       "-Dsonar.java.binaries=target/classes " + // 明确指定 Java 字节码目录
                       "-Dsonar.host.url=http://192.168.2.2:9000/ " + // 您的 SonarQube 服务器地址
                       "-Dsonar.login=admin " + // SonarQube 认证令牌或用户名
                       "-Dsonar.password=sonar " + // SonarQube 认证密码 (生产环境建议使用令牌)
                       "-Dsonar.coverage.jacoco.xmlReportPaths=${jacocoXmlReportPath}" // 关键:指定 JaCoCo XML 报告路径
                }
            }
        }
    }
}