Automate virtual device management with projected test rules

Applicable XR devices
This guidance helps you build experiences for these types of XR devices.
Audio &
Display Glasses

It's difficult to automate tests when the code depends on physical hardware. For example, you might need to manually connect and disconnect the physical device to verify connection states. With all the different types, capabilities, and device states of audio glasses and display glasses, this challenge can become even more complex. To test for this diverse set of cases, use the Projected Test Rule APIs to automate the setup and management of a projected test environment. The library handles projected device creation, connection states, and capability verification, so you can focus on testing your app's core logic. Use these APIs to build robust test suites without writing boilerplate code.

Add library dependencies

To use the test rule, add the testing artifact to your app's build.gradle file:

Groovy

dependencies {
// JXR Projected testing library
testImplementation "androidx.xr.projected:projected-testing:1.0.0-alpha07"
}

Kotlin

dependencies {
  // JXR Projected testing library
  testImplementation("androidx.xr.projected:projected-testing:1.0.0-alpha07")
}

Set up the test rule

To set up the basic test rule, annotate the rule in your test class. By default, the rule connects a projected device and enables its visual capabilities before each test is run.

@get:Rule
val projectedTestRule = ProjectedTestRule()

private val context: Context
    get() = ApplicationProvider.getApplicationContext()

@Test
fun testWithConnectedDevice() {
    val projectedContext = ProjectedContext.createProjectedDeviceContext(context)

    assertThat(ProjectedContext.isProjectedDeviceContext(projectedContext)).isTrue()
}

Test other common scenarios

Now that you've set up your projected test environment with a basic test rule, test other common scenarios for audio glasses and display glasses to verify your app's functionality.

Test device disconnection

To test how your app reacts when the connection with the glasses is lost, use the isDeviceConnected property:

@Test
fun testDeviceDisconnection() {
    // manually disconnect the device via the rule
    projectedTestRule.isDeviceConnected = false

    assertThrows(IllegalStateException::class.java) {
        ProjectedContext.createProjectedDeviceContext(context)
    }
}

Key points about the code

  • The rule resets properties like isDeviceConnected to their defaults before every test. You don't need to manually reset these properties in @After methods.

Test different device capabilities

Display glasses can show UIs built with Jetpack Compose Glimmer. By default, the ProjectedTestRule enables CAPABILITY_VISUAL_UI. To define exactly what the projected device supports, use the capabilities set. This is useful for verifying that your app correctly checks for hardware support before attempting to project content to the glasses.

@Test
fun testAppBehaviorWithoutDisplayCapabilities() = projectedTestRule.launchTestProjectedDeviceActivity { activity ->
    // disable display capability
    projectedTestRule.capabilities = setOf()

    runBlocking {
        // create the controller
        val controller = ProjectedDeviceController.create(activity)

        // verify the app recognizes the lack of visual UI support
        assertThat(controller.capabilities).doesNotContain(ProjectedDeviceController.Capability.CAPABILITY_VISUAL_UI)
    }
}

Key points about the code

  • The rule resets properties like capabilities to their defaults before every test. You don't need to manually reset these properties in @After methods.
  • When you need to verify behavior specifically for an activity that is projected to display glasses, use launchTestProjectedDeviceActivity.