You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SonarQube:如何在GitHub PR中添加多维度测试覆盖率质量门规则

如何在SonarQube质量门中分别管控单元测试与E2E测试覆盖率

可以实现这个需求,核心是将单元测试和E2E测试的覆盖率作为两个独立指标导入SonarQube,再在质量门中分别设置准入条件,具体步骤如下:

1. 分别生成单元测试与E2E测试的Jacoco覆盖率报告

确保你的构建工具(Gradle/Maven)能为单元测试和E2E测试分别生成独立的Jacoco XML格式报告(XML比.exec更适合SonarQube解析详细数据):

  • Gradle示例:在build.gradle中为两类测试任务配置Jacoco报告:
    jacoco {
        toolVersion = "0.8.10"
        reportsDirectory = file("$buildDir/reports/jacoco")
    }
    
    // 单元测试Jacoco配置
    tasks.named('test') {
        jacoco {
            enabled = true
            destinationFile = file("$buildDir/jacoco/test.exec")
        }
    }
    
    // E2E测试Jacoco配置(假设E2E测试任务名为e2eTest)
    tasks.named('e2eTest') {
        jacoco {
            enabled = true
            destinationFile = file("$buildDir/jacoco/e2eTest.exec")
        }
    }
    
    // 生成单元测试XML覆盖率报告
    task jacocoTestReport(type: JacocoReport) {
        dependsOn test
        executionData = file("$buildDir/jacoco/test.exec")
        reports {
            xml.required = true
            xml.outputLocation = file("$buildDir/reports/jacoco/test/jacocoTestReport.xml")
        }
    }
    
    // 生成E2E测试XML覆盖率报告
    task jacocoE2eTestReport(type: JacocoReport) {
        dependsOn e2eTest
        executionData = file("$buildDir/jacoco/e2eTest.exec")
        reports {
            xml.required = true
            xml.outputLocation = file("$buildDir/reports/jacoco/e2eTest/jacocoE2eTestReport.xml")
        }
    }
    
  • Maven示例:在pom.xml中配置Jacoco插件,为两类测试分别生成报告:
    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.10</version>
        <executions>
            <!-- 单元测试覆盖率配置 -->
            <execution>
                <id>jacoco-unit-test</id>
                <goals><goal>prepare-agent</goal></goals>
                <configuration>
                    <destFile>${project.build.directory}/jacoco/test.exec</destFile>
                </configuration>
            </execution>
            <execution>
                <id>jacoco-unit-report</id>
                <phase>test</phase>
                <goals><goal>report</goal></goals>
                <configuration>
                    <dataFile>${project.build.directory}/jacoco/test.exec</dataFile>
                    <outputDirectory>${project.reporting.outputDirectory}/jacoco/test</outputDirectory>
                    <formats><format>XML</format></formats>
                </configuration>
            </execution>
            <!-- E2E测试覆盖率配置 -->
            <execution>
                <id>jacoco-e2e-test</id>
                <phase>pre-integration-test</phase>
                <goals><goal>prepare-agent</goal></goals>
                <configuration>
                    <destFile>${project.build.directory}/jacoco/e2eTest.exec</destFile>
                    <propertyName>jacoco.e2e.agent.argLine</propertyName>
                </configuration>
            </execution>
            <execution>
                <id>jacoco-e2e-report</id>
                <phase>post-integration-test</phase>
                <goals><goal>report</goal></goals>
                <configuration>
                    <dataFile>${project.build.directory}/jacoco/e2eTest.exec</dataFile>
                    <outputDirectory>${project.reporting.outputDirectory}/jacoco/e2eTest</outputDirectory>
                    <formats><format>XML</format></formats>
                </configuration>
            </execution>
        </executions>
    </plugin>
    

2. 将E2E覆盖率作为自定义度量导入SonarQube

SonarQube默认不会区分单元和E2E覆盖率,因此需要提取E2E覆盖率数值作为自定义度量传入:

  • 在GitHub Actions的构建步骤中,添加脚本提取E2E测试的行覆盖率数值(以Gradle为例,用xmllint解析XML报告):
    - name: Extract E2E Coverage
      id: extract-e2e-coverage
      run: |
        # 解析Jacoco XML报告,计算行覆盖率百分比
        COVERED=$(xmllint --xpath "string(/report/counter[@type='LINE']/@covered)" build/reports/jacoco/e2eTest/jacocoE2eTestReport.xml)
        TOTAL=$(xmllint --xpath "string(/report/counter[@type='LINE']/@total)" build/reports/jacoco/e2eTest/jacocoE2eTestReport.xml)
        E2E_COVERAGE=$(echo "scale=2; $COVERED / $TOTAL * 100" | bc)
        echo "e2e_coverage=$E2E_COVERAGE" >> $GITHUB_OUTPUT
    
  • 在SonarQube扫描步骤中,传入自定义度量:
    - name: SonarQube Scan
      uses: SonarSource/sonarqube-scan-action@v2
      env:
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
      with:
        args: >
          -Dsonar.coverage.jacoco.xmlReportPaths=${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml
          -Dsonar.java.coveragePlugin=jacoco
          -Dsonar.customMetrics=e2e_coverage:float:2
          -Dsonar.e2e_coverage=${{ steps.extract-e2e-coverage.outputs.e2e_coverage }}
    
    说明:
    • sonar.customMetrics定义自定义度量:e2e_coverage为度量名称,float为数据类型,2为保留小数位数
    • sonar.e2e_coverage传入提取到的E2E覆盖率数值

3. 在SonarQube中配置质量门规则

登录SonarQube后台,进入质量门设置:

  • 保留原有的**单元测试覆盖率≥80%**条件(选择指标Coverage,设置条件为is less than 80时触发失败)
  • 添加新的E2E覆盖率条件:
    1. 选择自定义度量分类下的e2e_coverage
    2. 设置条件为is less than 70时触发失败
  • 保存质量门配置,并将其关联到你的项目

4. 验证流程

提交PR后,GitHub Actions会自动运行两类测试,提取E2E覆盖率并传入SonarQube,只有当单元测试覆盖率≥80%且E2E测试覆盖率≥70%时,PR才能通过质量门校验。

内容的提问来源于stack exchange,提问作者tuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:07:04