|  | # Tests as components | 
|  |  | 
|  | Caution: This document describes manifests for [components v1][components-v1]. | 
|  | The old architecture (components v1) implemented by `appmgr` is still in use, | 
|  | but will be removed once the transition to the new architecture is complete. | 
|  |  | 
|  | This document outlines the way for developers to configure their tests to run as | 
|  | Fuchsia components. This document is for developers working inside the Fuchsia | 
|  | source tree (`fuchsia.git`). The workflow described in this document is not | 
|  | suitable for the Fuchsia SDK-based developers. | 
|  |  | 
|  | The exact GN invocations used to produce a test may vary between different | 
|  | classes of tests and different languages. This document assumes that test logic | 
|  | is being built somewhere and the test binary is to be built to run as a Fuchsia | 
|  | component. For C++ and Rust, this would be the executable file that the build | 
|  | produces. (For information on writing tests in Rust, see | 
|  | [Testing Rust code][rust-testing].) | 
|  |  | 
|  | For an example setup of a test component, see | 
|  | <code>[//examples/hello_world/rust][hello-world-rust]</code>. | 
|  |  | 
|  | ## Fuchsia test environments | 
|  |  | 
|  | Tests on Fuchsia can run either as standalone executables (for example, | 
|  | [host tests][run-fuchsia-test]) or as components. Standalone executables are | 
|  | invoked within the environment the test runner is in, whereas components | 
|  | executed in a test runner run in a hermetic environment. These hermetic | 
|  | environments are fully separated from the host services. Test manifests | 
|  | determine whether new instances of services should be started in this | 
|  | environment, or services from the host should be plumbed in to the test | 
|  | environment. | 
|  |  | 
|  | ## Packaging a test as a component | 
|  |  | 
|  | To package a test as a component, you need to create the following: | 
|  |  | 
|  | *   [Component manifest](#component-manifest-for-a-test). | 
|  | *   [Package build rules](#package-build-rules-for-a-test-component) for the | 
|  | test executable and manifest. | 
|  |  | 
|  | Note: When writing simple unit tests that do not depend on any facets, features, | 
|  | or services in Fuchsia, you can create a test package using the | 
|  | <code>[fuchsia_unittest_package][fuchsia-unittest-package-gni]</code> template. | 
|  | This template lets the build system automatically generate a component manifest | 
|  | for these tests. | 
|  |  | 
|  | ### Component manifest for a test {#component-manifest-for-a-test} | 
|  |  | 
|  | A component manifest informs the component framework how to run a component. In | 
|  | this case, it explains how to run the test binary. A component manifest file | 
|  | (`.cmx`) is typically located in a `meta` directory next to the `BUILD.gn` file: | 
|  |  | 
|  | ```none | 
|  | <your_test_directory> | 
|  | ├── BUILD.gn | 
|  | ├── meta | 
|  | │   └── <component_manifest_file> | 
|  | ... | 
|  | ``` | 
|  |  | 
|  | When a package is built, it includes the component manifest file under a top | 
|  | level directory, which is also called `meta`. | 
|  |  | 
|  | The simplest possible component manifest for running a test may look like the | 
|  | following: | 
|  |  | 
|  | ```none | 
|  | { | 
|  | "program": { | 
|  | "binary": "test/hello_world_rust_bin_test" | 
|  | } | 
|  | } | 
|  | ``` | 
|  |  | 
|  | When you run the component above, it invokes the | 
|  | `test/hello_world_rust_bin_test` binary in the package. | 
|  |  | 
|  | However, the example manifest above may be inadequate for many use cases because | 
|  | the program running under this manifest has a very limited set of capabilities. | 
|  | For instance, there is no mutable storage available for this program and it | 
|  | cannot access any services in Fuchsia. | 
|  |  | 
|  | #### Sandbox | 
|  |  | 
|  | The `sandbox` portion of the manifest can be used to expand on this. As an | 
|  | alternative to the prior example, the following example provides the component | 
|  | access to storage at `/cache` and allows the component to talk to the service | 
|  | located at `/svc/fuchsia.logger.LogSink`: | 
|  |  | 
|  | ```none | 
|  | { | 
|  | "program": { | 
|  | "binary": "test/hello_world_rust_bin_test" | 
|  | }, | 
|  | "sandbox": { | 
|  | "features": [ "isolated-cache-storage" ], | 
|  | "services": [ "fuchsia.logger.LogSink" ] | 
|  | } | 
|  | } | 
|  | ``` | 
|  |  | 
|  | Test components can also have new instances of services created inside their | 
|  | test environment, thus isolating the impact of the test from the host. In the | 
|  | following example, the service available at `/svc/fuchsia.example.Service` is be | 
|  | handled by a brand new instance of the service referenced by the URL: | 
|  |  | 
|  | ```none | 
|  | { | 
|  | "program": { | 
|  | "binary": "test/hello_world_rust_bin_test" | 
|  | }, | 
|  | "facets": { | 
|  | "fuchsia.test": { | 
|  | "injected-services": { | 
|  | "fuchsia.example.Service": "fuchsia-pkg://fuchsia.com/example#meta/example_service.cmx" | 
|  | } | 
|  | } | 
|  | }, | 
|  | "sandbox": { | 
|  | "services": [ | 
|  | "fuchsia.example.Service" | 
|  | ] | 
|  | } | 
|  | } | 
|  | ``` | 
|  |  | 
|  | For more information on component manifests, see | 
|  | [Component manifests][component-manifest]. | 
|  |  | 
|  | ### Package build rules for a test component {#package-build-rules-for-a-test-component} | 
|  |  | 
|  | Once you have a component manifest, you can now add GN build rules in `BUILD.gn` | 
|  | to create a package for the test component. | 
|  |  | 
|  | The following example produces a new package named `hello-world-rust-tests` that | 
|  | contains the artifacts necessary to run a test component: | 
|  |  | 
|  | Note: The legacy GN templates for packages (`package.gni` and `test_package.gni`) | 
|  | are being deprecated. See | 
|  | [New GN templates for components v1](#new-gn-templates-for-components-v1) | 
|  | for details. | 
|  |  | 
|  | ```none | 
|  | import("//src/sys/build/fuchsia_unittest_package.gni") | 
|  |  | 
|  | fuchsia_unittest_component("hello-world-rust-test-component") { | 
|  | executable_path = "test/hello_world_rust_bin_test" | 
|  | component_name = "hello-world-rust-test" | 
|  | deps = [ ":bin" ] | 
|  | } | 
|  |  | 
|  | fuchsia_test_package("hello-world-rust-tests") { | 
|  | test_components = [ | 
|  | ":hello-world-rust-test-component", | 
|  | ] | 
|  | } | 
|  | ``` | 
|  |  | 
|  | The example above requires that the `:bin` target produces a test binary named | 
|  | `hello_world_rust_bin_test`. The | 
|  | <code>[fuchsia_unittest_package][fuchsia-unittest-package-gni]</code> | 
|  | template requires that `meta/${TEST_NAME}.cmx` exists and that the destination | 
|  | of the test binary matches the target name. In the example, this means that | 
|  | `meta/hello_world_rust_bin_test.cmx` must exist. | 
|  |  | 
|  | This template produces a package in the same way that the | 
|  | <code>[fuchsia_package][fuchsia-package-gni]</code> template does, but it | 
|  | has extra checks in place to ensure that the test is set up properly. For | 
|  | more information, see [Test packages][test-packages]. | 
|  |  | 
|  | ## New GN templates for components v1 {#new-gn-templates-for-components-v1} | 
|  |  | 
|  | The legacy GN templates for packages | 
|  | (<code>[test_package.gni][test-package-gni]</code> and | 
|  | <code>[package.gni][package-gni]</code>) are being deprecated in favor | 
|  | of the following new templates: | 
|  |  | 
|  | *   <code>[fuchsia_package.gni][fuchsia-package-gni]</code> | 
|  | *   <code>[fuchsia_test_package.gni][fuchsia-test-package-gni]</code> | 
|  | *   <code>[fuchsia_unittest_package.gni][fuchsia-unittest-package-gni]</code> | 
|  |  | 
|  | For instance, the examples below demonstrate how you can rewrite | 
|  | the `test_package` template's build rules using the | 
|  | `fuchsia_unittest_package` template: | 
|  |  | 
|  | *   {`test_package`} | 
|  |  | 
|  | ```none | 
|  | import("//build/test/test_package.gni") | 
|  |  | 
|  | test_package("hello-world-rust-tests") { | 
|  | deps = [ | 
|  | ":bin", | 
|  | ] | 
|  | tests = [ | 
|  | { | 
|  | name = "hello_world_rust_bin_test" | 
|  | } | 
|  | ] | 
|  | } | 
|  | ``` | 
|  |  | 
|  | *    {`fuchisa_unittest_package`} | 
|  |  | 
|  | ```none | 
|  | import("//src/sys/build/fuchsia_unittest_package.gni") | 
|  |  | 
|  | fuchsia_unittest_component("hello-world-rust-test-component") { | 
|  | executable_path = "test/hello_world_rust_bin_test" | 
|  | component_name = "hello-world-rust-test" | 
|  | deps = [ ":bin" ] | 
|  | } | 
|  |  | 
|  | fuchsia_test_package("hello-world-rust-tests") { | 
|  | test_components = [ | 
|  | ":hello-world-rust-test-component", | 
|  | ] | 
|  | } | 
|  | ``` | 
|  |  | 
|  | For more examples on these templates, see [Test component][test-component]. | 
|  |  | 
|  | <!-- Reference links --> | 
|  |  | 
|  | [components-v1]: /docs/glossary.md#components-v1 | 
|  | [hello-world-rust]: /examples/hello_world/rust | 
|  | [run-fuchsia-test]: /docs/development/testing/run_fuchsia_tests.md | 
|  | [component-manifest]: /docs/concepts/components/v1/component_manifests.md | 
|  | [rust-testing]: /docs/development/languages/rust/testing.md | 
|  | [test-package-gni]: /build/test/test_package.gni | 
|  | [package-gni]: /build/package.gni | 
|  | [test-packages]: /docs/development/components/build.md#test-packages | 
|  | [fuchsia-package-gni]: /src/sys/build/fuchsia_package.gni | 
|  | [fuchsia-test-package-gni]: /src/sys/build/fuchsia_test_package.gni | 
|  | [fuchsia-unittest-package-gni]: /src/sys/build/fuchsia_unittest_package.gni | 
|  | [test-component]: /docs/concepts/testing/test_component.md |