{% set rfcid = “RFC-0180” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
{# Fuchsia RFCs use templates to display various fields from _rfcs.yaml. View the #} {# fully rendered RFCs at https://fuchsia.dev/fuchsia-src/contribute/governance/rfcs #}
This RFC is a design proposal for the Test UI Stack component, which will provide ui-specific testing capabilities to test clients both in- and out- of-tree.
Integration testing is essential for Fuchsia petal stability. However, there are few out-of-tree (“OOT”) hermetic UI integration tests today, because OOT clients face significant barriers to writing them. Namely, they must:
The Test UI Stack component aims to mitigate these issues by handling low-level UI details on behalf of test clients.
Who has a stake in whether this RFC is accepted? (This section is optional but encouraged.)
Facilitator:
Reviewers:
Consulted:
List people who should review the RFC, but whose approval is not required.
Socialization:
This RFC went through a design review with the Fuchsia Testing and Fuchsia Input teams. We also consulted OOT UI client teams.
We propose a Test UI Stack component, to be added to the Fuchsia partner SDK, which will expose a facade of the production UI realm. Concretely, this component will expose the following services:
A client can instantiate this component, route required UI services to the component(s) under test, present a view to the scene, and use the various helper services provided to drive its tests.
Note that this design is agnostic to how the UI stack and test component configure their respective realms. They could do so statically or via RealmBuilder.
Initially, the Test UI Stack will include the following base UI components, which mirror the “modern” production UI stack at the time of writing:
Furthermore, the Test UI Stack will initially expose the following base UI services to the test:
Note that the Test UI Stack can and will evolve to mirror the production one.
Depending on the progress of the One UI Stack migration, we may also add a “legacy” variant of the Test UI Stack component that uses root presenter and input pipeline in place of scene manager.
Along with the base UI components referenced above, the Test UI Stack will include a set of narrowly-scoped helper components to provide low-level UI-specific capabilities to clients via higher-level APIs. At launch, this set may include:
The Test UI Stack will expose helper services from these components, which clients can use to drive tests.
The helper component abstraction offers several important benefits:
Some clients may need to configure parameters like display rotation, pixel density, etc. The Test UI Stack can accommodate these use cases with structured component configuration. Clients can override parameters they wish to control, which the Test UI Stack component can then propagate to the appropriate base UI components.
The pseudo-C++ snippet below outlines a basic touch input test using the Test UI Stack component.
// 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(...);
Workstreams enumerated below can proceed in parallel.
This workstream enables test to attach a view to the scene, which is a hard reqeuirement for any graphics/input test.
fuchsia.ui.observation.geometry
protocol available OOT in the SDK.This workstream enables OOT clients to use geometry observer data agnostic to the root of the scene graph, which may vary across different products and UI stack configurations.
This workstream enables OOT Test UI Stack users to inject input; today, there is no alternative.
Once the workstreams above have completed, we can assemble the Test UI Stack package in the partner SDK, and add it to the product build(s) against which OOT clients run their tests.
This design targets integration tests that are already multi-component, so we expect the proposed extensions of test topology to have minimal performance implications.
Some OOT tests may actually see improved performance, because they can rely on more stable synchronization patterns.
There are no security considerations for this RFC. Since the test UI stack doesn‘t consume any system capabilities (except sysmem and vulkan), it is incapable of doing anything a normal end-user vulkan program couldn’t do.
The Test UI Stack has no access to private or sensitive resources, so there are no privacy considerations for this RFC.
We can achieve sufficient confidence in the Test UI Stack's behavior as we write tests to use it.
We intend to publish a developer guide explaining how to use the Test UI Stack.
The proposed design leaves clients with some common boilerplate to write. We may be able to eliminate this pain point with a custom UI-specific implementation of fuchsia.test.Suite
, which would enable clients to plug a test client and test logic into a predefined UI test framework.
See original UI Test Manager RFC.