使用gitlab-ci.yml文件生成代码覆盖率报告

41

我需要在Gitlab中查看Java Maven项目的代码覆盖率报告。

根据这里这里和其他一些来源:

  1. 我已将pom.xml中的jacoco加入插件列表。
  2. 向我的.gitlab-ci.yml文件添加了pages作业。
  3. 将代码覆盖率解析添加到项目设置中,代码为:Total.*?([0-9]{1,3})%

但是我并没有看到任何覆盖率报告,至少我看不到。 没有覆盖率百分比或覆盖率报告页面。

.gitlab-ci.yml文件的内容如下:

image: maven:latest

variables:
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"

cache:
  paths:
    - .m2/repository/

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test
  artifacts:
    paths:
      - target/site/jacoco/
pages:
  stage: deploy
  dependencies:
    - test
  script:
   - mkdir public
   - mv target/site/jacoco/index.html public
  artifacts:
    paths:
      - public

deploy:
  stage: deploy
  script:
    - mvn $MAVEN_CLI_OPTS verify
  only:
    - master

pom.xml 中的 jacoco 插件:

Translated:

The jacoco plugin in pom.xml:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.5.201505241946</version>
    <executions>
        <execution>
            <id>pre-unit-test</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>post-unit-test</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

我的项目是在 gitlab.com 上的私有项目。

流水线和其中的所有 4 个任务都已成功通过。

我该如何查看覆盖率报告?


最近我遇到了同样的问题,我在这里记录了我的解决方案 https://notes.jfsanchez.net/post/109-gitlab-coverage-from-jacoco-reports - Jorge F. Sanchez
9个回答

46

看起来你在.gitlab-ci.yml文件中忘记添加对cat的调用了。

你应该像这样:

script:
    - mvn $MAVEN_CLI_OPTS test
    - cat target/site/jacoco/index.html

话虽如此,我认为这不是最好的方法,因为你需要在输出中添加原始HTML代码才能获得所需的覆盖率值。我建议使用此拉取请求中描述的方法:https://github.com/jacoco/jacoco/pull/488
  • Keep the jacoco parts in your build.xml
  • Use this awk instruction to print the correct code coverage total:

    awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print covered, "/", 
    instructions, "instructions covered"; print 100*covered/instructions, "% 
    covered" }' target/site/jacoco/jacoco.csv
    
  • Replace the Gitlab CI regexp with what the instruction returns: \d+.\d+ \% covered

编辑:

从Gitlab 8.17开始,你可以在.gitlab-ci.yml文件中直接定义正则表达式,如文档所述。

这可能看起来多余,但如果这个正则表达式现在是您的存储库历史的一部分,那么您可以与其他用于计算它的工具一起更改它。


1
如果您使用多模块项目,可以执行以下命令:awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print 100*covered/instructions, "% tu covered" }' find . -name "jacoco.csv"`` - Corentin

18

我是一名GitLab员工。

如果您的管理员已设置了GitLab页面,您可以通过转到项目中的 设置 -> 页面 来查看部署工件的URL。

这里您应该能看到:

恭喜!您的页面已经提供服务于: https://your-namespace.example.com/your-project

点击链接即可访问!我们还在扩展对HTML工件的支持。这个问题及其相关问题讨论了现有和即将推出的功能,这些功能可能会扩展您在此构建的内容。


4
谢谢。我找到了页面和覆盖报告HTML文件的链接。但是这个文件只包含简单的代码覆盖百分比。你知道如何查看代码覆盖率吗?我的意思是看到被覆盖的代码像绿线,未被覆盖的代码像红线或类似的东西? - AshKan

16

除了@SKBo所说的内容外,我想添加一个小调整。

执行

cat target/site/jacoco/index.html

会使你的构建输出变得混乱,难以阅读其中重要的内容。

我建议改为:

cat your/path/to/jacoco/report/index.html | grep -o '<tfoot>.*</tfoot>'

这样可以大大减少杂音。


链接现在是jacoco/report/html/index.html因此,最终的命令将是cat your/path/to/jacoco/report/html/index.html | grep -o '<tfoot>.*</tfoot>' - Skandy

9
为了显示基本的总覆盖百分比,您只需要:
test:
  stage: test
  image: maven:3.6.3-jdk-11
    - mvn $MAVEN_CLI_OPTS test
    - cat target/site/jacoco/index.html | grep -o 'Total[^%]*%'
  coverage: '/Total.*?([0-9]{1,3})%/'
  artifacts:
    paths:
      - target/site/jacoco/jacoco.xml
    expire_in: 1 mos
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

如果您想启用代码覆盖率可视化功能:

visualize_test_coverage:
  stage: visualize_test_coverage
  image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
  script:
    - 'python /opt/cover2cover.py target/site/jacoco/jacoco.xml src/main/java > target/site/cobertura.xml'
    - 'python /opt/source2filename.py target/site/cobertura.xml'
  needs: [ "test" ]
  dependencies:
    - test
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: target/site/cobertura.xml
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

要获取详细信息,请查看官方Gitlab文档这里


嗨@magiccrafter,我的目标文件夹没有自动获取jacoco文件夹,我该怎么办? - Deepanshu Rathi

8

我在.gitlab-ci.yml文件中使用了这个命令

cat target/site/jacoco-merge/index.html | grep -o 'Total[^%]*%' | sed 's/<.*>/ /; s/Total/Jacoco Coverage Total:/'

这将打印一个漂亮的字符串,不带混乱和HTML标签:

Jacoco Coverage Total: 39%

然后您可以使用GitLab文档中提到的正则表达式:

Total.*?([0-9]{1,3})%

或者您可以使用:

Jacoco Coverage Total: ([0-9]{1,3})%

6

我正在使用以下代码:

镜像: maven:latest
sonarqube-check: 脚本: - mvn verify sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_TOKEN -Dsonar.qualitygate.wait=true - cat target/site/jacoco/index.html | grep -o '.*' 允许失败: false 覆盖率: "/Total.*?([0-9]{1,3})%/"

1

完整的CI示例,基于之前的答案,适用于单元测试和集成测试

test:
  stage: test
  image: maven:3.8-openjdk-17-slim
    - mvn $MAVEN_CLI_OPTS verify
      # jacoco code-coverage reporting
    - if [ -f target/site/jacoco/index.html ]; then awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print 100*covered/instructions, "% covered" }' target/site/jacoco/jacoco.csv; fi
    - if [ -f target/site/jacoco-it/index.html ]; then awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print 100*covered/instructions, "% covered" }' target/site/jacoco-it/jacoco.csv; fi
  coverage: '/([0-9.]*) % covered/'

1
这个简短的awk脚本从jococo.csv文件中提取百分比,而不是尝试解析HTML输出。
#!/bin/sh

# This awk script calculates a code coverage %
# usage: pass the the jacoco.csv file as first argument

awk -F "," '
    {
      instructions += $4 + $5; covered += $5
    }
    END {
      print covered, "/", instructions, "instructions covered";
      printf "%.2f%% covered\n", covered / instructions * 100
    }' "$1"

输出:

coverage.sh target/site/jacoco/jacoco.csv 
369992 / 469172 instructions covered
78.86% covered

你应该调整printf格式以匹配你的Gitlab覆盖率正则表达式。

请注意,也可以使用 #!/usr/bin/awk shebang,但由于与不同发行版和版本的gawk存在一些兼容性问题,因此它的可移植性较差。 - istepaniuk

0
新增一个工作,执行脚本。
awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print int(100*covered/instructions), "% covered" }' target/site/jacoco/jacoco.csv

获取此内容

覆盖率为74%


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接