RFC-0163:测试输出格式

RFC-0163:测试输出格式
状态已接受
领域
  • 测试
说明

定义但尚未使用由 ffx 测试生成的测试输出格式的初始稳定版本。

问题
  • 81195
Gerrit 更改
  • 649303
作者
审核人
提交日期(年-月-日)2022-02-22
审核日期(年-月-日)2022-05-18

之前的 API 设计文档

此 RFC 之前是作为 API 设计文档提交的,并在 API 设计文档模板被废弃后转换为 RFC。

总结

本文档通过 fuchsia SDK 提供的测试工具提出了一种基于目录的稳定格式输出。

目标和应用场景

通过测试架构,客户端可以同时安排和执行多个测试,还可以为每个测试收集大量诊断工件。ffx test 充当主机工具,客户端可通过该工具与测试架构进行交互。

调用 ffx test 的自动化工具(例如在 CI 基础架构中运行的工具)需要通过一种方式可靠地获取测试执行期间生成的全套结果和工件。目前,这些工具通过解析 stdout 获取测试结果,但 stdout 比较脆弱,无法表达测试架构收集的全部工件。此设计旨在提供针对机器解析进行优化的稳定输出格式。

如果采用稳定的磁盘格式,开发者还可以在测试运行后检查结果,或与其他开发者分享结果。

ffx test 供 SDK 使用方在树外使用。为了确保这些用户的工具不会因工具更新而损坏,格式必须具有稳定性。

此输出格式并不旨在替换表示测试成功或失败的所有信号。例如,ffx test 仍然支持人类可读的输出以及指示成功或失败的返回代码。

背景

单次执行 ffx test 会产生一次测试运行。测试运行由多个套件组成,每个套件由测试用例组成。

“套件运行”是指对测试组件的执行。测试组件最常通过其网址标识,例如 fuchsia-pkg://fuchsia.com/run_test_suite_integration_tests#meta/passing-test-example.cm。在测试运行中,同一套件可能会运行多次。在这种情况下,存在多个单独的套件运行

测试用例是指对套件中包含的单个测试用例执行。同一测试用例可以在套件运行内运行多次。在这种情况下,有多个测试用例

工件是测试架构收集的诊断输出。工件的范围限定为测试运行、测试套件运行或测试用例。例如,目前的测试架构会针对每个测试用例收集 stdout 和 stderr,但会针对每个测试套件运行收集 syslog。

设计

概览

测试输出存储为目录。目录的根目录包含单个 JSON 文件和任意数量的子目录。子目录会包含作用域限定为单个测试用例、测试套件或测试运行的工件。该 JSON 文件包含测试结果、测试作业详情,并列出了目录中包含的工件。

目录布局

JSON 文件始终名为 run_summary.json,并且始终位于目录的顶层。run_summary.json 包含整体测试运行、测试运行中的套件运行以及每次套件运行中的测试用例的完整集。它还包含每个工件子目录的名称及其中的工件列表。

未指定子目录的名称以及其中的工件。子目录和工件的实际名称在 run_summary.json 中定义。工件始终位于工件子目录的顶层。

JSON 架构

JSON Schemata 将放置在 //sdk/schema/ffx_test 下,并通过 SDK 导出。架构演变将依赖于 RFC-0100 中引入的架构版本控制机制。

架构的初始版本在此提交中定义。

不同工具的使用情况

需要解读测试结果的工具应首先解析 run_summary.json,这是输出格式中唯一指定了位置的文件。run_summary.json 包含一组完整的结果和对所有工件的引用。工具不应假定输出结果中的其他位置都是稳定的。

未知

输出格式可能会根据用户需求更新。例如,我们可能会更新格式以简化我们发现的常见用例中的解析。

易用性

可扩展性和演进

我们预计的主要扩展是添加新的测试状态和工件类型。一般来说,架构的其他枚举变体和 JSON 字段不属于重大更改,使用输出的工具可以放心地忽略字段和枚举它们不理解的变体。重大更改包括对必填字段的修改以及对目录结构的更改。在这些情况下,系统将按照 RFC-0100 中的策略生成并发布新版 JSON 架构。

类似的输出

在 Fuchsia 之外,还有许多单独的测试框架,这些框架支持多种机器可读的测试结果格式。例如,googletest 同时支持 JSON 和 XML 输出格式。

测试

测试将主要依赖于单元测试和集成测试,这些测试用于验证 ffx test 生成的输出是否符合输出格式。

性能注意事项

生成此文件格式应该不会花费大量时间。一个原型实现,用于保存一个包含 100,000 个测试用例的套件(每个测试用例都包含 stdout 和 stderr 工件)不到一秒的时间来生成并持久保留 run_summary.json(磁盘占用的存储空间约为 26 MB)。假设有 100 万个用例,同一原型需要大约 15 秒才能生成 run_summary.json,大约需要占用磁盘 256 MB。在所有情况下,原型的最大内存用量都是磁盘上摘要大小的两倍左右。

相比之下,Chromium 中的一个大型已知测试套件大约包含 100,000 个用例。由于针对此数量的情形保存 run_summary.json 只需不到一秒的时间,因此这应该不会造成问题。

在 fuchsia.git 中,目前最大的测试套件包含大约 300 到 400 个测试用例,单个基础架构分片可能包含大约 300 个套件。对于 fuchsia.git,我们打算使用 ffx 测试的多重测试功能,这会将所有测试用例的结果保存在单个输出目录中。因此,对于这种情况,我们预计 run_summary.json 中最多会有 120,000 个病例,据我们估计,占用磁盘不到 50 MB 的空间,节省大约 1 秒的时间。

有许多常见的本地开发流程,开发者会重复运行测试。例如,开发者可能会反复运行测试,以重现不稳定的故障。在这种情况下,我们可以轻松地运行数千个测试用例的批量,而不会超过 10 MB 的内存用量。

安全注意事项

此输出仅用于存储测试生成的结果和工件,并且已由测试框架提供,不会引入额外的安全注意事项。

隐私注意事项

此输出仅用于存储测试生成的结果和工件,并且已由测试框架提供,不会引入其他隐私保护注意事项。

缺点和替代方案

默认情况下,输出格式支持多次运行测试套件。对于每次只运行一项测试的客户端,这会使解析变得复杂。一种替代方案是支持一种输出格式(包含单个测试套件运行的结果)和另一种输出格式(包含多次测试套件运行的结果)。虽然这样可以简化即时解析,但采用多种格式会使分析输出的共享工具变得复杂。

另一种方法是使用多个 JSON 文件来存储测试结果。使用单个文件存储所有测试结果的一个缺点是,与该文件交互的工具必须一次性将全部内容保存在内存中。从原型设计来看,在 run_summary.json 超过 1 GB 之前,我们需要大约 400 万个测试用例,此时序列化大约需要一分钟时间。由于我们当前的用例比这要少一个数量级,因此尚不需要多个文件。由于将结果存储到多个文件中,会使解析变得复杂,因此我们将使用单个文件。

第三种方法是将所有工件存储在 run_summary.json 中,以进一步简化解析。这样做的缺点是,工件现在也需要保存在内存中。目前收集的最大工件是用于覆盖率的配置文件数据。在单个基础架构分片中,此配置数据约为 500 MB,拆分到多个文件中。虽然此配置文件不会超过 1 GB,但只要更改测试分片方式和配置文件数据的表示方式,就能快速使大小接近 1 GB。