RFC-0180:测试界面堆栈

RFC-0180:测试界面堆栈
状态已接受
领域
  • 查看系统
说明

此 RFC 是测试界面堆栈组件的设计方案,该组件将提供特定于界面的测试功能,以便测试树内和树外客户端。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-06-16
审核日期(年-月-日)2022-07-26

摘要

此 RFC 是测试界面堆栈组件的设计方案, 提供特定于界面的测试功能,以测试客户端 树状结构。

设计初衷

集成测试对于 Fuchsia 花瓣稳定性至关重要。不过, 目前只有少数几种树外(“OOT”)封闭界面集成测试,因为 OOT 都会面临很大的障碍。也就是说,他们必须:

  • 了解界面堆栈的秘密,通常远远超出了他们的讨论范围 生产环境用例。
  • 将测试行为与界面堆栈的内部实现详情进行耦合。
  • 使用仅限内部使用的 FIDL API 来运行相关的界面组件。
  • 设计测试,使其能够灵活适应环境中正在进行的各种迁移 界面堆栈(GFX ->Flatland、Root Presenter ->Scene Manager、CFv1 -> CFv2)。

测试界面堆栈组件旨在通过处理低级别任务来缓解这些问题 代表测试客户端的界面详细信息。

用例示例

  • 适用于客户端运行时的触摸/鼠标/键盘输入测试:对于这些测试, 客户端将启动测试界面堆栈,将视图附加到场景中,然后等待 直到视图树状态停止,注入输入,并观察其视图 处理了传入事件。
  • 应用测试:这些测试可以运行应用的某些部分 并观察它如何渲染内容、处理输入 与无障碍功能等互动
  • 界面相邻测试:一些不明确执行界面的测试 功能可能仍需要存在界面。例如, fuchsia.web 可能需要测试客户端呈现视图

利益相关方

谁对是否接受此 RFC 有影响?(此部分为可选内容, encouraged.)

教员

leannogasawara@google.com

审核者

  • Fuchsia 测试架构:crjohns@google.com
  • UI + OOT 集成测试:dworsham@google.com、jaeheon@google.com

已咨询

列出应审查 RFC 但无需批准的人员。

  • 输入:quiche@google.com、neelsa@google.com
  • 无障碍功能:neelsa@google.com、lucasradaelli@google.com
  • 组件框架:yaneury@google.com、geb@google.com、cgonyeo@google.com
  • Flutter:akbiggs@google.com
  • Chromium:sergeyu@google.com
  • Opal:cligh@google.com、anwilson@google.com、robinsontom@google.com

社交化

此 RFC 通过了 Fuchsia Testing 和 Fuchsia 的设计审核 输入团队。我们还咨询了 OOT 界面客户团队。

术语库

  • 界面堆栈:一组提供基本界面服务的 Fuchsia 组件。 大体而言,这组内容包括风景、根 Presenter 或场景管理器、输入 无障碍功能管理器、快捷方式管理器和文本管理器。
  • 测试界面堆栈:公开了界面堆栈 Facade 的提议组件 (基本界面服务 + 帮助程序服务)。
  • 基本 UI 服务:从生产 UI 公开的服务集 Realm
  • 帮助程序服务:代理底层界面功能的仅供测试用的服务 通过更高级别的 API 发送给客户端。
  • 场景:视图的层次结构。 可让所有者向显示屏呈现可渲染内容、使用输入 以及如何与无障碍功能互动

设计

要求

  • 涉及界面的封闭式 OOT 集成测试必须易于编写。
  • 涉及界面的封闭式 OOT 集成测试必须可读。
  • 测试功能不得泄露界面堆栈的内部信息。
  • 客户端必须能够配置包含界面堆栈的测试领域。
  • 客户端必须能够扩展测试界面定义的组件拓扑 用于包含测试专用配置的堆栈。
  • 必须保证测试能够设置和清理。
  • 测试必须相互隔离。
  • 测试界面堆栈不得排除 RealmBuilder 的使用。
  • 客户必须能够使用他们选择的语言编写测试。

建议

  • 树内和树外界面集成测试应直接

概览

我们提议将一个测试界面堆栈组件添加到 Fuchsia 合作伙伴 SDK 中, 这将公开生产界面领域的 Facade。具体而言, 组件将公开以下服务:

  1. 大致来说,这组公共服务在生产界面之外公开。
  2. 一组仅供测试用的“帮助程序服务”提供低级别界面功能 (例如输入合成、屏幕截图等)。

客户端可以实例化此组件,将所需的界面服务路由到 被测组件、向场景呈现视图以及使用各种辅助程序 来推动其测试

替代文本:
显示的组件拓扑:
测试管理器 ->测试夹具组件
测试夹具组件 ->测试界面堆栈组件
测试夹具组件 ->测试界面客户端
测试夹具组件 ->支持组件
测试夹具组件 ->本地模拟
测试界面堆栈组件 ->帮助程序组件
测试界面堆栈组件 ->基本界面组件服务路由
辅助组件 ->测试界面堆栈组件(帮助程序服务)
基础界面组件 ->测试界面堆栈组件(基本界面服务)
测试界面堆栈组件 ->测试夹具组件(基本界面服务、帮助程序)
服务)
测试界面堆栈组件 ->测试界面客户端 (base ui services)
测试界面客户端 ->测试夹具组件 (fuchisa.ui.app.ViewProvider)
支持组件 ->测试界面客户端(支持服务)
本地模拟 ->测试界面客户端(模拟服务)

请注意,此设计与界面堆栈和测试组件 配置它们各自的领域。他们可以通过静态方式或通过 RealmBuilder

基本界面拓扑

最初,测试界面堆栈将包含以下基础界面组件, 这体现了“现代”的生产界面堆栈:

  1. 风景秀丽,配置为使用平地。
  2. 场景管理器
  3. 无障碍管理器
  4. 文字管理器
  5. 快捷方式管理器
  6. Cobalt(不是界面组件,但运行环境所需的资源)
  7. 模拟的硬件显示控制器(同样,不是界面组件,而是必需组件 风景名胜)

此外,测试界面堆栈最初会公开以下基础界面 要测试的服务:

  1. fuchsia.accessibility.semantics.SemanticsManager
  2. fuchsia.ui.composition.Allocator
  3. fuchsia.ui.composition.Flatland
  4. fuchsia.ui.scenic.Scenic
  5. fuchsia.ui.input.ImeService
  6. fuchsia.ui.input3.Keyboard
  7. fuchsia.ui.input3.KeyEventInjector
  8. fuchsia.ui.shortcut.Manager
  9. fuchsia.ui.shortcut.Registry

请注意,测试界面堆栈可能会并且将演变,以反映正式版界面堆栈。

根据单一界面堆栈迁移的进度, 我们可能还会添加“旧版”测试界面堆栈组件的变体, root Presenter 和输入流水线,用以取代场景管理器。

辅助组件

除了上面提到的基础界面组件之外,测试界面堆栈还会 包含一组范围较小的辅助组件,以提供 通过更高级别的 API 向客户提供特定于界面的功能。发布时, 包括:

  1. 一种输入合成组件,可让客户端注入文本、鼠标 直接输入到输入管道中。
  2. 一种屏幕截图组件,可让客户端截取屏幕截图 。
  3. 场景提供程序组件,用于将客户端视图附加到场景,以及 代表其注册特权功能(例如限定范围的几何体) 观察器)。请注意,由于场景提供程序代表 因此测试界面堆栈无需公开任何观察器注册表 服务。

测试界面堆栈将公开这些组件中的帮助程序服务, 来推动测试

帮助程序组件抽象有几个重要优势:

  • 抽象:帮助程序服务呈现一个稳定、定义完善的立面, 客户端,这有助于最大限度地减少对界面堆栈内部的依赖。
  • 简单性:通过专用帮助程序组件出售界面功能 确保每个 FIDL API 都简单而具体,从而改善了 DX 的编写和 来维护界面测试
  • 可扩展性:我们可以通过添加新的帮助程序,轻松扩展界面 Facade 组件。
  • 与子包的兼容性:我们可以改用不含任何子包的子包 即客户端函数损失。

可配置性

某些客户端可能需要配置屏幕旋转、像素 测试界面堆栈可以适应这些具有结构化 组件 配置。 客户端可以覆盖他们想要控制的参数 然后,测试界面堆栈组件可将其传播到相应的基础界面 组件。

应用示例

下面的伪 C++ 代码段概述了使用测试界面的基本触控输入测试 堆栈组件。

// Client test code creates a RealmBuilder instance.
component_testing::RealmBuilder realm_builder;

// Instantiate Test UI Stack component by absolute URL in the test realm.
realm_builder.AddChild("test-ui-stack",
            "fuchsia-pkg://fuchsia.com/test-ui-stack#meta/test-ui-stack.cm");

// Add a test view component to the test realm, and route required UI services
// to it.
realm_builder.AddChild("test-view", ...);
realm_builder.AddRoute({
    .capabilities = {Protocol{fuchsia::ui::scenic::Scenic::Name_}},
    .source = ChildRef{"test-ui-stack"},
    .targets = {"test-view"}},
}});

// Expose fuchsia.ui.app.ViewProvider from the test view.
realm_builder.AddRoute({
    .capabilities = {Protocol{fuchsia::ui::app::ViewProvider::Name_}},
    .source = ChildRef{"test-view"},
    .targets = {ParentRef()}},
}});

// Build the test realm.
RealmRoot realm_root = realm_builder_.Build();

// Connect to the scene provider "helper service", and request to attach a
// test view to the scene.
std::optional<zx_koid_t> client_view_ref_koid;
fuchsia::ui::observation::geometry::Provider geometry_provider;
auto scene_provider = realm_root->Connect<fuchsia::ui::test::scene::Provider>();
auto view_provider = realm_root_->Connect<fuchsia::ui::app::ViewProvider>();
scene_provider->AttachView(std::move(view_provider), geometry_provider.NewRequest(),
  [&client_view_ref_koid](auto view_ref_koid) {
    // Save the client's ViewRef koid.
    client_view_ref_koid = view_ref_koid;
  });

// Wait for client view ref koid to become available.
RunLoopUntil([&client_view_ref_koid] {
  return client_view_ref_koid.has_value();
});

// Use registered geometry provider to wait for client view to render.
ASSERT_TRUE(geometry_provider.is_bound());
geometry_provider.Watch(...);
RunLoopUntil(...);

// Connect to input synthesis helper service, and use to inject input.
auto input_synthesis = realm_root->Connect<fuchsia::ui::test::input::Touch>();
input_synthesis->InjectTap(...);

实现

下面枚举的工作流可以并行进行。

工作流:场景提供程序帮助程序服务

  1. 陆地 FIDL 变更。
  2. 实现场景提供程序辅助组件。
  3. 重构现有的树内测试,以使用场景提供程序。

此工作流使测试能够将视图附加到场景, 所有图形/输入测试的要求。

工作流:几何图形观察器

  1. 使 fuchsia.ui.observation.geometry 协议在 SDK 中以开箱即用。
  2. 实现“限定范围”几何图形观测器注册表。

此工作流使 OOT 客户端可以使用与 场景图的根,可能会因产品和界面而异 堆栈配置。

工作流:输入合成

  1. 重新设计了输入合成 API 以供 OOT 使用。
  2. 向 SDK 添加输入合成 FIDL 库。
  3. 实现 FIDL 库。

此工作流可让 OOT 测试界面堆栈用户注入输入;今天,有 没有替代方法。

工作流:重构树内 UITestManager 库

  1. 将领域配置从现有的内部 UITestManager 类中分解出来, 转换为新的 UITestRealm 类,该类可与测试界面堆栈共享。
  2. (可选)实现与生产界面共享 .cml 的机制 子领域。如果不是现在,我们应该在 One UI Stack 完成 迁移完毕

完成上述工作流后,我们就可以组建测试界面堆栈了 软件包,并将其添加到 OOT 所针对的产品 build 由客户运行测试

性能

此设计针对的是已经是多组件的集成测试,因此我们 预计所提议的测试拓扑扩展的性能会非常低 影响。

一些 OOT 测试实际上可能会发现性能有所提升,因为它们可以依赖于 更稳定的同步模式

安全注意事项

此 RFC 没有安全注意事项。由于测试界面堆栈 不消耗任何系统功能(sysmem 和 vulkan 除外), 执行任何普通最终用户 vulkan 程序无法执行的操作。

隐私注意事项

测试界面堆栈无权访问私有或敏感资源,因此 此 RFC 没有隐私权注意事项。

测试

在编写代码时,我们可以对测试界面堆栈的行为获得足够的信心 才能使用它

文档

我们打算发布一份开发者指南,说明如何使用测试界面堆栈。

缺点、替代方案和未知问题

缺点

跨客户端重复样板

所提议的设计会为客户端留下一些要编写的通用样板。周三 我们也许可以通过专门针对特定界面的自定义界面 fuchsia.test.Suite 的实现,它使客户端能够插入 测试客户端和测试逻辑集成到预定义的界面测试框架中。

考虑的备选方案

请参阅原始的 UI Test Manager RFC