单元测试报告

CI/CD 流水线 通常包含验证您的代码的测试作业。 如果测试失败,流水线将失败并通知用户。处理合并请求的人必须检查作业日志并查看测试失败的地方,以便可以修复它们。

您可以将作业配置为使用单元测试报告,极狐GitLab 会显示有关合并请求的报告,以便更轻松、更快速地识别故障,而无需检查整个日志。单元测试报告目前仅支持 JUnit 报告格式的测试报告。

如果您不使用合并请求但仍希望在不搜索作业日志的情况下查看单元测试报告输出,则流水线中提供完整的单元测试报告详细视图。

考虑以下工作流程:

  1. 您的默认分支坚如磐石,您的项目正在使用 GitLab CI/CD,并且您的流水线表明没有任何损坏。
  2. 您团队中的某个人提交了合并请求,测试失败并且流水线获得已知红色图标。要进行更多调查,您必须查看作业日志来找出测试失败的原因,这些日志通常包含数千行。
  3. 您配置单元测试报告,极狐GitLab 立即收集并在合并请求中公开它们,您不再需要在作业日志中搜索。
  4. 您的开发和调试工作流程变得更容易、更快、更高效。

工作原理

首先,GitLab Runner 上传所有 JUnit 报告格式 XML 文件到极狐GitLab,作为产物。然后,当您访问合并请求时,极狐GitLab 开始比较 head 和 base 分支的 JUnit 报告格式 XML 文件,其中:

  • base 分支是目标分支(通常是默认分支)。
  • head 分支是源分支(每个合并请求中的最新流水线)。

报告面板有一个摘要,显示有多少测试失败、有多少错误以及有多少已修复。如果由于 base 分支的数据不可用而无法进行比较,则面板仅显示 head 的失败测试列表。

有四种类型的结果:

  1. 新失败的测试:测试用例在 base 分支上通过,在 head 分支上失败
  2. 新遇到的错误:测试用例在 base 分支上通过,但由于 head 分支上的测试错误而失败
  3. 现有故障:测试用例在 base 分支上失败,在 head 分支上失败
  4. 已解决的故障: 测试用例在 base 分支上失败,在 head 分支上通过

面板中的每个条目都显示了上面列表中的测试名称及其类型。单击测试名称会打开一个窗口,其中包含其执行时间和错误输出的详细信息。

Test Reports Widget

最近失败的次数

如果过去 14 天内项目的默认分支中的测试失败,则会为该测试显示一条消息,如 Failed {n} time(s) in {default_branch} in the last 14 days

如何设置

要在合并请求中启用单元测试报告,您必须在 .gitlab-ci.yml 中添加 artifacts:reports:junit,并指定生成测试报告的路径。 报告必须是 .xml 文件,否则极狐GitLab 返回错误 500。

在以下示例中,test 阶段的作业运行,极狐GitLab 从每个作业中收集单元测试报告。执行每个作业后,XML 报告作为产物存储在极狐GitLab 中,其结果显示在合并请求部件中。

要使单元测试报告输出文件可浏览,请将它们包含在 artifacts:paths 关键字中,如 Ruby 示例 中所示。 即使作业失败(例如,如果测试未通过)也要上传报告,请使用 artifacts:when:always 关键字。

JUnit 报告格式 XML 文件中不能有多个具有相同名称和类的测试。

Ruby example

.gitlab-ci.yml 中使用以下作业,包括 artifacts:paths 关键字来提供指向单元测试报告输出文件的链接。

## Use https://github.com/sj26/rspec_junit_formatter to generate a JUnit report format XML file with rspec
ruby:
  stage: test
  script:
    - bundle install
    - bundle exec rspec --format progress --format RspecJunitFormatter --out rspec.xml
  artifacts:
    when: always
    paths:
      - rspec.xml
    reports:
      junit: rspec.xml

Go example

.gitlab-ci.yml 中使用以下作业:

## Use https://github.com/gotestyourself/gotestsum to generate a JUnit report format XML file with go
golang:
  stage: test
  script:
    - go get gotest.tools/gotestsum
    - gotestsum --junitfile report.xml --format testname
  artifacts:
    when: always
    reports:
      junit: report.xml

Java examples

有一些工具可以在 Java 中生成 JUnit 报告格式的 XML 文件。

Gradle

在以下示例中,gradle 用于生成测试报告。 如果定义了多个测试任务,gradle 会在 build/test-results/ 下生成多个目录。在这种情况下,您可以通过定义以下路径来利用全局匹配:build/test-results/test/**/TEST-*.xml

java:
  stage: test
  script:
    - gradle test
  artifacts:
    when: always
    reports:
      junit: build/test-results/test/**/TEST-*.xml

在 GitLab Runner 13.0 及更高版本中,您可以使用 **

Maven

用于解析 SurefireFailsafe 测试报告,在 .gitlab-ci.yml 中使用以下作业:

java:
  stage: test
  script:
    - mvn verify
  artifacts:
    when: always
    reports:
      junit:
        - target/surefire-reports/TEST-*.xml
        - target/failsafe-reports/TEST-*.xml

Python example

此示例使用带有 --junitxml=report.xml 标志的 pytest 将输出格式化为 JUnit 报告 XML 格式:

pytest:
  stage: test
  script:
    - pytest --junitxml=report.xml
  artifacts:
    when: always
    reports:
      junit: report.xml

C/C++ example

有一些工具可以在 C/C++ 中生成 JUnit 报告格式的 XML 文件。

GoogleTest

在以下示例中,gtest 用于生成测试报告。 如果为不同的架构(x86x64arm)创建了多个 gtest 可执行文件,则需要运行每个测试并提供唯一的文件名。然后将结果汇总在一起。

cpp:
  stage: test
  script:
    - gtest.exe --gtest_output="xml:report.xml"
  artifacts:
    when: always
    reports:
      junit: report.xml

CUnit

当在运行时使用它的 CUnitCI.h 宏,CUnit自动生成 JUnit 报告格式 XML 文件

cunit:
  stage: test
  script:
    - ./my-cunit-test
  artifacts:
    when: always
    reports:
      junit: ./my-cunit-test.xml

.NET example

JunitXML.TestLogger NuGet 包可以为 .Net Framework 和 .Net Core 应用程序生成测试报告。以下示例需要仓库根文件夹中的解决方案,子文件夹中包含一个或多个项目文件。每个测试项目生成一个结果文件,每个文件都放置在 artifacts 文件夹中。这个例子包括可选的格式化参数,它提高了测试部件中测试数据的可读性。

## Source code and documentation are here: https://github.com/spekt/junit.testlogger/

Test:
  stage: test
  script:
    - 'dotnet test --test-adapter-path:. --logger:"junit;LogFilePath=..\artifacts\{assembly}-test-result.xml;MethodFormat=Class;FailureBodyFormat=Verbose"'
  artifacts:
    when: always
    paths:
      - ./**/*test-result.xml
    reports:
      junit:
        - ./**/*test-result.xml

JavaScript example

有一些工具可以在 JavaScript 中生成 JUnit 报告格式的 XML 文件。

Jest

jest-junit npm 包可以为 JavaScript 应用程序生成测试报告。 在以下 .gitlab-ci.yml 示例中,javascript 作业使用 Jest 生成测试报告:

javascript:
  stage: test
  script:
    - 'jest --ci --reporters=default --reporters=jest-junit'
  artifacts:
    when: always
    reports:
      junit:
        - junit.xml

Karma

Karma-junit-reporter npm 包可以为 JavaScript 应用程序生成测试报告。 在以下 .gitlab-ci.yml 示例中,javascript 作业使用 Karma 生成测试报告:

javascript:
  stage: test
  script:
    - karma start --reporters junit
  artifacts:
    when: always
    reports:
      junit:
        - junit.xml

Mocha

JUnit Reporter for Mocha NPM 包可以为 JavaScript 应用程序生成测试报告。 在以下 .gitlab-ci.yml 示例中,javascript 作业使用 Mocha 生成测试报告:

javascript:
  stage: test
  script:
    - mocha --reporter mocha-junit-reporter --reporter-options mochaFile=junit.xml
  artifacts:
    when: always
    reports:
      junit:
        - junit.xml

Flutter / Dart example

此示例 .gitlab-ci.yml 文件使用 JUnit Report 包将 flutter test 输出转换为 JUnit 报告 XML 格式:

test:
  stage: test
  script:
    - flutter test --machine | tojunit -o report.xml
  artifacts:
    when: always
    reports:
      junit:
        - report.xml

PHP example

此示例使用带有 --log-junit 标志的 PHPUnit。 您还可以在 phpunit.xml 配置文件中使用 XML 添加此选项。

phpunit:
  stage: test
  script:
    - composer install
    - vendor/bin/phpunit --log-junit report.xml
  artifacts:
    when: always
    reports:
      junit: report.xml

在极狐GitLab 上查看单元测试报告

如果生成 JUnit 报告格式 XML 文件并将其作为流水线的一部分上传,则可以在流水线详细信息页面中查看这些报告。此页面上的 测试 选项卡显示从 XML 文件报告的测试套件和案例列表。

Test Reports Widget

您可以查看所有已知的测试套件并选择其中的每一个以查看更多详细信息,包括组成该套件的案例。

单元测试报告解析错误

引入于 13.10 版本

如果解析 JUnit 报告 XML 导致错误,作业名称旁边会显示一个指示符。将鼠标悬停在图标上会在工具提示中显示解析器错误。如果多个解析错误来自分组作业,仅显示该组中的第一个错误。

Test Reports With Errors

极狐GitLab 不会解析非常大的节点 的 JUnit 报告。

在极狐GitLab 上查看 JUnit 屏幕截图

将您的屏幕截图作为产物上传到极狐GitLab。如果 JUnit 报告格式 XML 文件包含 attachment 标签,极狐GitLab 会解析附件。注意:

  • attachment 标签必须包含您上传的屏幕截图的 $CI_PROJECT_DIR 的相对路径。例如:

    <testcase time="1.00" name="Test">
      <system-out>[[ATTACHMENT|/path/to/some/file]]</system-out>
    </testcase>
    
  • 您应该将上传屏幕截图的作业设置为 artifacts:when: always,以便在测试失败时仍然上传屏幕截图。

测试用例附件的链接出现在流水线测试报告的测试用例详细信息中。