Google is committed to advancing racial equity for Black communities. See how.

Write a Host-side Deviceless Test in TF

This page tells you how to write a host-side test that doesn’t require a device, such as a test that runs on a Linux GCE instance. (For details about writing a host-driven test that requires a device, refer to Write a Host-driven Test in Trade Federation.)

Host-side test types

You can run several types of host-side tests through Trade Federation (TF).

Native (gtest) tests

Create Native tests (gtests) to test a platform. If the test doesn’t require a device, run it on a host; the test will run much faster that way. To configure such tests to run on a test host, use the TF runner HostGTest.

This is a sample TradeFed test configuration:

<configuration description="Runs hello_world_test.">
    <option name="null-device" value="true" />
    <test class="com.android.tradefed.testtype.HostGTest" >
        <option name="module-name" value="hello_world_test" />
    </test>
</configuration>

The test configuration runs a gtest test (hello_world_test) on a host. The example test config can be auto-generated. Unless your test needs a special setup or cleanup, you can rely on auto test-config generation to create proper TF test configurations.

To configure a host-side gtest and enable auto test- config generation, set host_supported to true in Android.bp, as in hello_world_test.

For more information about writing a native test, see Adding a New Native Test Example.

JAR (Java) host tests

JAR host tests, such as JUnit, are tests that don’t need to run on a device, and that provide code coverage of your Java project. Such tests can be configured to run on a test host by using the runner HostTest.

Sample TradeFed test configuration:

<configuration description="Executes HelloWorldHostTest">
    <test class="com.android.tradefed.testtype.HostTest" >
        <option name="jar" value="HelloWorldHostTest.jar" />
    </test>
</configuration>

The test configuration runs a host-side JUnit test of HelloWorldHostTest. Note that the above test configuration can be auto-generated. Unless your test needs special setup or cleanup, rely on the auto test-config generation to create proper TradeFed test configuration.

For more details about how to write a JAR host test, refer to the JAR (Java) Host Tests page.

Isolated Java host tests

Deviceless Java tests can be run in an isolation environment with a slight performance cost. However, there are some major considerations to be made before choosing to use this environment.

  • This is the default runner used for Robolectric and JUnit unit tests
  • Tradefed supports only JUnit tests in the isolation environment.
  • Only statically linked dependencies are supported. No dependencies declared with lib are included on the classpath.
  • The isolation runner only puts the shim runner and your test jar on the classpath.
  • There is some amount of fixed overhead per test run executed with this runner.

Sample Tradefed test configuration (isolated)

<configuration description="Executes HelloWorldHostTest">
    <test class="com.android.tradefed.testtype.IsolatedHostTest" >
        <option name="jar" value="HelloWorldHostTest.jar" />
    </test>
</configuration>

Sample Soong configuration for autogeneration

Instead of manually creating the test config like above, Soong can autogenerate the config by using a declaration like this example.

java_test_host {
    name: "HelloWorldHostTest",

    test_options: {
        unit_test: true,
    },

    test_suites: ["general-tests"],

    srcs: ["test/**/*.java"],

    static_libs: [
        "junit",
    ],
}

Robolectric tests

Robolectric tests use the same runner as the isolated host tests, with a few special options.

  • The robolectric-resources option enables a few Robolectric-specific command line options to be passed into the subprocess as well as adds the tree build of android-all to the subprocess classpath. While the other two are best practices, this option is mandatory for running Robolectric tests with any success.
  • The java-folder option allows changing the Java runtime used by the subprocess. This is necessary due to Robolectric preferring particular Java versions that might not align with the host system's preferred JVM.
  • The exclude-paths option allows the subprocess runner to avoid loading particular modules at all, which is useful when a JAR comes with extraneous classes that could cause load errors. java. is a common exclusion, to avoid throwing SecurityException exceptions.

Sample Robolectric config

<configuration description="Executes a Sample Robolectric Test">
    <option name="java-folder" value="prebuilts/jdk/jdk9/linux-x86/" />
    <option name="exclude-paths" value="java" />
    <option name="use-robolectric-resources" value="true" />
    <test class="com.android.tradefed.testtype.IsolatedHostTest">
        <option name="jar" value="RobolectricExampleTest.jar" />
    </test>
</configuration>

Sample Soong configuration for Robolectric autogeneration

Instead of manually creating the test config like above, Soong can autogenerate the config by using a declaration like this example.

android_robolectric_test {
    name: "HelloWorldRoboTest",
    srcs: [
        "src/**/*.java",
    ],

    // Include the testing libraries
    static_libs: [
        "mockito-robolectric-prebuilt",
        "platform-test-annotations",
        "testng",
        "truth-prebuilt",
    ],

    instrumentation_for: "HelloWorldApp",
}

Python test

If the test logic is written in Python, use build type python_test_host to create a par file that can be run by TF PythonBinaryHostTest.

Sample TradeFed test configuration

<configuration description="Config to run atest unittests">
    <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest" >
        <option name="par-file-name" value="atest_unittests" />
        <option name="test-timeout" value="2m" />
    </test>
</configuration>

Test suite setting

For the host-side test to be accessible by TF for a given build, set the test module `test_suites` setting to `general-tests`:

test_suites: ["general-tests"],

With this setting, the test is packaged to general-tests.zip on the test_suites target.