xcresultparser

概述

解析来自 Xcode 构建和测试运行的二进制 xcresult 包。

解释二进制 .xcresult 文件,并以不同格式打印摘要

对于测试结果,使用 'xml' JUnit 格式;对于覆盖率数据,使用通用格式(Sonarqube)。

您还可以指定项目根目录的名称。路径和 URL 将相对于指定的目录。(用于 XML 输出中的 URL)

此工具可以使用 Xcode 13 中包含的开发者工具从 .xcarchive 读取测试结果数据和代码覆盖率数据。 具体来说,这里使用 xcresulttool 和 xccov 从 .xcresult 包获取 JSON 数据。

使用强大的 XCResultKit 包进行 JSON 解析。

转换代码覆盖率数据

遗憾的是,转换为适用于 Sonarqube 等工具的代码覆盖率 XML 格式是一项繁琐的任务。它需要我们为项目中的每个文件调用 xccov 二进制文件。

首先,我们使用 xccov --file-list 从 archive 获取包含覆盖率数据的源文件列表,然后我们需要为每个文件调用 xccov。 这会花费大量时间。因此,至少我们可以将其分布在不同的线程上,使其并行执行并且总体速度更快。

到目前为止,我们一直使用 xccov-to-sonarqube-generic.sh,它执行相同的工作,只是使用 shell 脚本。它存在同样的问题,并且因为它无法将其派生到不同的线程,因此花费的时间大约是 5 倍。

直到 Xcode 13 之前,情况一直如上所述。 Xcode 13 带来了新版本的 xccov 命令行工具,该工具现在可以一次性输出所有覆盖率数据。无需再为每个 Swift 文件调用 xccov 这么繁琐了!因此,Sonar 提供的 shell 脚本 xccov-to-sonarqube-generic.sh 执行此任务的速度与 xcresultparser 相同。 这使得此工具的最初目的变得无用。但是,xcresultparser 现在可以完成更多技巧,而不仅仅是将 xcresult 包中的覆盖率数据转换为适用于 Sonarqube 的 XML 格式。

如果您只想在终端中,以 HTML 或 Markdown 格式显示 xcresult 包的内容(测试),那么它仍然对您有用,以便用于构建链中。

感谢 Thibault Wittemberg 和 maxwell-legrand 的合作,它也可以用于 Cobertura。

此外,它可以从 xcresult 包中提取 JUnit 格式的测试数据,也适用于 Sonarqube。

如何获取

使用 homebrew

brew tap a7ex/homebrew-formulae
brew install xcresultparser

下载二进制文件

chmod +x ~/Desktop/xcresultparser

或者自己构建工具

如何安装

使用 homebrew

brew tap a7ex/homebrew-formulae
brew install xcresultparser

已下载的二进制文件

假设 xcresultparser 应用在您的桌面上…

打开一个终端窗口并运行此命令

cp ~/Desktop/xcresultparser /usr/local/bin/

在终端中运行此命令,验证 xcresultparser 是否在您的搜索路径中

xcresultparser

您应该看到该工具像这样响应

Error: Missing expected argument '<xcresult-file>'

OVERVIEW: xcresultparser 1.8.4
Interpret binary .xcresult files and print summary in different formats: txt,
xml, html or colored cli output.

USAGE: xcresultparser [<options>] [<xcresult-file>]

ARGUMENTS:
  <xcresult-file>         The path to the .xcresult file.

OPTIONS:
  --coverage-report-format <coverage-report-format>
                          The coverage report format. The Default is 'methods',
                          It can either be 'totals', 'targets', 'classes' or
                          'methods'
  -o, --output-format <output-format>
                          The output format. It can be either 'txt', 'cli',
                          'html', 'md', 'xml', 'junit', 'cobertura',
                          'warnings', 'errors' and 'warnings-and-errors'. In
                          case of 'xml' sonar generic format for test results
                          and generic format (Sonarqube) for coverage data is
                          used. In the case of 'cobertura', --coverage is
                          implied.
  -p, --project-root <project-root>
                          The name of the project root. If present paths and
                          urls are relative to the specified directory.
  -t, --coverage-targets <coverage-targets>
                          Specify which targets to calculate coverage from. You
                          can use more than one -t option to specify a list of
                          targets.
  -e, --excluded-path <excluded-path>
                          Specify which path names to exclude. You can use more
                          than one -e option to specify a list of path patterns
                          to exclude. This option only has effect, if the
                          format is either 'cobertura' or 'xml' with the
                          --coverage (-c) option for a code coverage report or
                          if the format is one of 'warnings', 'errors' or
                          'warnings-and-errors'.
  -s, --summary-fields <summary-fields>
                          The fields in the summary. Default is all:
                          errors|warnings|analyzerWarnings|tests|failed|skipped
  -c, --coverage          Whether to print coverage data.
  -n, --no-test-result    Whether to print test results.
  -f, --failed-tests-only Whether to only print failed tests.
  -q, --quiet             Quiet. Don't print status output.
  -i, --target-info       Just print the targets contained in the xcresult.
  -v, --version           Show version number.
  -h, --help              Show help information.

既然 xcresultparser 的副本已在您的搜索路径中,请从您的桌面删除它。

您已准备就绪!🎉

如何使用

该工具不会创建任何文件。它只是将其结果输出到标准输出。您需要使用重定向将输出写入文件。例如,如果您想将文本输出写入桌面上的名为 output.txt 的文件中

xcresultparser -o txt test.xcresult > ~/Desktop/output.txt

但是,如果您只需要将 xcresult 包的内容输出到终端

xcresultparser -o cli test.xcresult

您还可以使用以下命令合并两个 xcresult 文件

xcrun xcresulttool merge Result1.xcresult Result2.xcresult --output-path=Result_merged.xcresult

对于 xcresultparser >= 1.5.2,您现在可以调用:xcresultparser Result_merged.xcresult --output-format=junit

它遍历所有可用的测试操作。它为每个测试操作创建一个测试套件。它将测试套件的总体测试时间设置为所有测试套件时间的总和。

示例

彩色 CLI 输出

将测试结果以彩色打印到命令行

xcresultparser -o cli test.xcresult

Colored command line output

HTML 输出

创建一个包含测试数据的单个 HTML 文件

xcresultparser -o html test.xcresult > testResult.html

Interactive single page HTML file

Junit 输出

创建一个 JUnit 格式的 XML 文件

xcresultparser -o junit test.xcresult > junit.xml

Sonarqube 输出

创建一个通用测试执行 XML 格式的 XML 文件

xcresultparser -o xml test.xcresult > sonarTestExecution.xml

创建一个适用于所有目标的通用代码覆盖率 XML 格式的 XML 文件

xcresultparser -c -o xml test.xcresult > sonarCoverage.xml

创建一个通用代码覆盖率 XML 格式的 XML 文件,但仅适用于两个目标 "foo" 和 "baz"

xcresultparser -c -o xml test.xcresult -t foo -t baz > sonarCoverage.xml

Cobertura XML 输出

创建 Cobertura 格式的 XML 文件

xcresultparser -o cobertura test.xcresult > cobertura.xml

请注意,此文件中的某些数据在撰写本文时是伪造的,但应具有准确的行覆盖率信息。它应该足以导入到诸如 GitLab 覆盖率可视化工具

如果您希望更改 Cobertura 报告中的文件名和源文件(请参阅下面的注释) - 对于 GitLab 兼容性是必需的,那么还可能需要传递 --project-root。

Markdown 输出

用于测试结果的简单 Markdown 格式。(我们将其用于在 Teams Webhook 中显示)

xcresultparser -o md test.xcresult > teamsWebhook.txt

Code Climate 输出

Code Climate 检查的 JSON 输出

xcresultparser -o warnings test.xcresult > climate.json

错误输出

描述错误的 JSON 输出

xcresultparser -o errors test.xcresult > errors.json

关于 Sonarqube 扫描器的路径

从 xcresult archive 获取数据的工具会产生绝对路径名。 因此,您必须为 sonar-scanner CLI 工具的 sonar.sources 参数提供绝对路径名,并且它必须与 xcodebuild 运行测试并创建 .xcresult archive 的目录匹配。

如果您想将测试结果用于 Sonarqube,则还有另一个问题:.xcresult 包仅按 testclass 列出测试,而不是按文件列出。 但是,Sonarqube CLI 工具期望测试的文件路径。 在这种情况下,您必须为 xcresultparser 提供 --project-root。 只有这样,xcresultparser 才能通过 egrep-ing ^(?:public )?(?:final )?(?:public )?(?:(class|\@implementation) )\w+ 将类名转换为文件名。 如果在 --project-root 中提供的目录中找到这样的文件,则可以确定文件路径,并且 sonar-scanner 可以顺利扫描文件以查找测试。 该模式匹配所有 Swift 和 Objective-C 类。

由于搜索 project-root 中的所有文件需要一些时间,因此会预先创建一个用于类名的索引路径名,并将其用作查找表。

以下 egrep 表达式用于为类的文件名创建查找表

egrep -rio --include "*.swift" --include "*.m" "^(?:public )?(?:final )?(?:public )?(?:(class|\@implementation) )\w+" $project-root

如果 xcresult archive 不是在同一台机器上创建的,并且用于 sonar-scanner 的路径不同,则需要调整路径名。 在这种情况下,您可以为 sonar-scanner CLI 工具的 sonar.sources 参数使用相对路径,并将 xcresultparser 的输出转换为也返回相对路径名。 参数 -p 或 --project-root 接受一个字符串,以便查找和删除路径名的开头,以便它们是相对的。 这样做的方式相当简单… 在绝对路径中搜索使用 --project-root 提供的字符串,如果找到,则将路径截断到包含提供的字符串为止。 示例: ./xcresultparser -c -o xml --project-root "work/myApp/" test.xcresult > sonar.xml xcresult 中的示例路径: /Users/alex/work/myApp/Sources/myApp/SomeClass.swift 将被转换为: Sources/myApp/SomeClass.swift 现在请确保您从项目的根目录中调用 sonar-scanner,并使用相对路径 "Sources" 作为 sonar.sources 的参数。