解析来自 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。
brew tap a7ex/homebrew-formulae
brew install xcresultparser
xcresultparser.zip
二进制文件xcresultparser
复制到您的桌面chmod +x ~/Desktop/xcresultparser
或者自己构建工具
swift build -c release
来构建 xcresultparser
可执行文件open .build/release
以在 Finder 中打开包含可执行文件的目录xcresultparser
可执行文件从 Finder 窗口拖到您的桌面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
它遍历所有可用的测试操作。它为每个测试操作创建一个测试套件。它将测试套件的总体测试时间设置为所有测试套件时间的总和。
将测试结果以彩色打印到命令行
xcresultparser -o cli test.xcresult
创建一个包含测试数据的单个 HTML 文件
xcresultparser -o html test.xcresult > testResult.html
创建一个 JUnit 格式的 XML 文件
xcresultparser -o junit test.xcresult > junit.xml
创建一个通用测试执行 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 文件
xcresultparser -o cobertura test.xcresult > cobertura.xml
请注意,此文件中的某些数据在撰写本文时是伪造的,但应具有准确的行覆盖率信息。它应该足以导入到诸如 GitLab 覆盖率可视化工具。
如果您希望更改 Cobertura 报告中的文件名和源文件(请参阅下面的注释) - 对于 GitLab 兼容性是必需的,那么还可能需要传递 --project-root。
用于测试结果的简单 Markdown 格式。(我们将其用于在 Teams Webhook 中显示)
xcresultparser -o md test.xcresult > teamsWebhook.txt
Code Climate 检查的 JSON 输出
xcresultparser -o warnings test.xcresult > climate.json
描述错误的 JSON 输出
xcresultparser -o errors test.xcresult > errors.json
从 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 的参数。