RFC-0163:测试输出格式

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

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

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

之前的 API 设计文档

此 RFC 之前以 API 设计文档的形式提交,后来在 API 设计文档模板被弃用后转换为 RFC。

摘要

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

目标和使用场景

测试架构允许客户端同时安排和执行多项测试,并且还会为每项测试收集大量诊断制品。ffx test 用作主机工具,客户端可通过该工具与测试架构进行交互。

调用 ffx test 的自动化工具(例如在 CI 基础架构中运行的工具)需要一种可靠的方法来获取测试执行期间生成的一整套结果和制品。目前,这些工具通过解析标准输出来获取测试结果,这种方式不够灵活,无法表达测试架构收集的完整制品集。此设计旨在提供稳定的输出格式,以便机器进行解析。

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

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 架构将放置在 //sdk/schema/ffx_test 下,并通过 SDK 进行导出。架构演变将依赖于 RFC-0100 中引入的架构版本控制机制。

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

各工具的用量

需要解读测试结果的工具应先解析 run_summary.json,这是输出格式中唯一具有已定义位置的文件。run_summary.json 包含完整的结果集以及对所有制品的引用。工具不应假设输出中的任何其他位置是稳定的。

未知

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

易用性

可扩展性和发展

我们预计的主要扩展包括添加新的测试状态和制品类型。一般来说,向架构添加枚举变体和 JSON 字段不会造成重大变更,使用输出的工具可以放心地忽略它们不了解的字段和枚举变体。 重大更改包括对必需字段的修改以及对目录结构的更改。在这些情况下,系统会根据 RFC-0100 中的策略在 SDK 中生成并发布新版本的 JSON 架构。

类似输出

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

测试

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

性能考虑因素

生成此文件格式预计不会花费大量时间。一个用于保存包含 10 万个测试用例的测试套件的原型实现,每个测试用例都有 stdout 和 stderr 制品,生成和持久化 run_summary.json(磁盘上大约 26 MB)所需的时间不到 1 秒。假设有 100 万个病例,同一原型生成 run_summary.json 大约需要 15 秒,磁盘上的大小约为 256 MB。在所有情况下,原型在内存中的最大用量约为磁盘上摘要大小的两倍。

相比之下,Chromium 中一个已知的大型测试套件包含大约 10 万个测试用例。由于保存这 run_summary.json 个案例的耗时不到 1 秒,因此这应该不会造成问题。

在 fuchsia.git 中,目前最大的测试套件包含大约 300-400 个测试用例,而单个基础设施分片可能包含大约 300 个套件。对于 fuchsia.git,我们打算使用 ffx test 的多测试功能,该功能会将所有测试用例的结果保存在一个输出目录中。因此,在这种情况下,我们预计 run_summary.json 中最多会有大约 12 万个用例,我们估计这些用例在磁盘上占用的空间不到 50 MB,保存时间约为 1 秒。

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

安全注意事项

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

隐私注意事项

此输出仅用于存储测试生成的结果和制品,并且已由测试框架提供,不会带来额外的隐私权考虑因素。

缺点和替代方案

输出格式默认支持多次测试套件运行。这会使一次只运行一个测试的客户端的解析变得复杂。一种替代方案是支持一种包含单次测试套件运行结果的输出格式,以及另一种包含多次测试套件运行结果的输出格式。虽然这简化了立即解析,但多种格式会使分析输出的共享工具变得复杂。

另一种替代方案是使用多个 JSON 文件来存储测试结果。使用单个文件存储所有测试结果的一个缺点是,与该文件交互的工具必须一次将全部内容保存在内存中。根据原型,我们需要大约 400 万个测试用例,run_summary.json 才会超过 1GB,此时序列化大约需要 1 分钟。由于我们目前的使用情形比此值低一个数量级,因此尚不需要多个文件。由于将结果存储在多个文件中会使解析变得复杂,因此我们将使用单个文件。

第三种替代方法是将所有制品存储在 run_summary.json 中,以进一步简化解析。这种方法也有缺点,即工件现在也需要保存在内存中。目前收集的最大制品是用于覆盖率分析的配置文件数据。在单个基础架构分片中,此个人资料数据约为 500 MB,分布在多个文件中。虽然此配置文件未超过 1GB,但如果测试分片方式和配置文件数据表示方式发生变化,很快就会使大小接近 1GB。