Write foldable tests quickly with Test Kit

Kristen Halper

Hello Android developers!

This week, we’re super excited to announce that we’ve released the first version of our foldable Test Kit. The Test Kit currently includes two testing utility libraries, one for layouts built with views and another for layouts built with Jetpack Compose, and we’re looking forward to adding more testing capabilities in the future!

Library overview

The goal of these testing libraries is to make it easier to write UI tests for foldables. We’ve included several different helper methods for creating mock folding features, simulating spanning gestures, and other useful utilities. To learn more about the Test Kit, refer to the documentation.

One important note is that the Compose library is based on the view system library, so you only need to import one version in any project. If you’re only using views, then you should import the view system library:

com.microsoft.dualscreen.testing:testing-kotlin

Otherwise, you should import the Compose library:

com.microsoft.dualscreen.testing:testing-compose

View system library

The view system library is the basis of the Test Kit and was originally created because we found ourselves using the same helper functions over and over again in our UI tests. When you import the library, you’ll have access to the following utilities:

  1. CurrentActivityDelegate

    Set up and support a test scenario from an ActivityTestRule and helps you to ensure that the Activity is running before to use any view or assertion, and any configuration change.

  2. DeviceModel & UiDeviceExtensions

    Simulate dual-screen swipe gestures on both Surface Duo models and change device orientation.

  3. FoldingFeatureHelper

    Simulate folding features with different properties, including those of other foldable devices, with the Jetpack Window Manager testing artifact.

  4. ForceClick

    Simulate a force click with a ViewAction extension used specifically after configuration changes.

  5. ViewMatcher

    Check if a view is shown in the display area given its position and screen dimensions.

  6. WindowLayoutInfoConsumer.

    Monitor and reset WindowLayoutInfo data in a test activity.

Compose library

The Compose library builds on the view system library by adding helper functions that are useful for Compose UI tests. When you import this library, you’ll have access to all of the functionality described above, in addition to the following Compose utilities:

  1. FoldingFeatureHelper

    Provides Compose wrappers for the FoldingFeatureHelper methods from the view system library.

  2. StringHelper

    Access string resources during UI tests with an AndroidComposeTestRule.

Write foldable tests with less code

If you’ve been following our blog in the past, you may have seen our posts about foldable testing tips with Espresso and Jetpack Compose.

@Test 
fun isAppSpanned() {
    val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) 

    // span the app (from the left side) 
    device.swipe(675, 1780, 1350, 900, 400)        

    // test a UI element 
    onView(withText("your-text-to-test")).check(matches(isDisplayed())) 
}

Code snippet from Surface Duo testing tips & tricks blog post for spanning during an Espresso test

You may have also tried out foldable testing in the Jetpack Window Manager codelab.

@Test
fun testText_is_left_of_Vertical_FoldingFeature() {
   activityRule.scenario.onActivity { activity ->
       val hinge = FoldingFeature(
           activity = activity,
           state = FLAT,
           orientation = VERTICAL,
           size = 2
       )
       val expected = TestWindowLayoutInfo(listOf(hinge))
       publisherRule.overrideWindowLayoutInfo(expected)
   }

   // Add Assertion with EspressoMatcher here
}

Code snippet from JWM codelab for simulating a folding feature

Either way, you can see how these code snippets could be hard to understand from a beginner’s point-of-view and could lead to mistakes due to incorrect swipe coordinates or folding feature properties. With the Test Kit, our goal was to make tests more readable and easier to write. In the modified code snippets below, you can see how the same tests would look when using our libraries:

@Test 
fun isAppSpanned() {
    val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
  	
    // span the app (from the left side) 
    device.spanFromStart()

    // test a UI element 
    onView(withText("your-text-to-test")).check(matches(isDisplayed())) 
}

Updated code snippet based on Surface Duo testing tips & tricks blog post that uses the Test Kit to span during an Espresso test

@Test
fun testText_is_left_of_Vertical_FoldingFeature() {
   publisherRule.simulateVerticalFoldingFeature(activityRule, size = 2, state = FLAT)

   // Add Assertion with EspressoMatcher here
}

Updated code snippet based on JWM codelab that uses the Test Kit to simulate a folding feature

You can see how you no longer need to calculate the exact coordinates for a swipe; in the library, we dynamically determine the coordinates by checking the size and orientation of a device. And for simulating folding features, it’s a lot easier to focus on passing in the relevant properties now that the boilerplate code is part of the helper method implementation.

Add to your project

When writing your own foldable tests, we hope you also find that the Test Kit makes the whole process easier!

To import the Test Kit, follow these steps:

  1. Make sure you have the mavenCentral() repository in your top-level build.gradle file:

    allprojects {
        repositories {
            google()
            mavenCentral()
         }
    }
  2. Ensure the compileSdkVersion and targetSdkVersion are set to API 31 or newer in your module-level build.gradle file:

    android { 
        compileSdkVersion 31
        defaultConfig { 
            targetSdkVersion 31 
        } 
        ...
    }
  3. Add one of the following dependencies to your module-level build.gradle file:

    View system library

    implementation "com.microsoft.dualscreen.testing:testing-kotlin:1.0.0-alpha2"

    Compose library

      implementation "com.microsoft.dualscreen.testing:testing-compose:1.0.0-alpha03"

Once you’ve imported the correct library version, you can start setting up your test classes and writing tests. To test UI behavior on foldables, you have two options: swipe gestures or mock folding features.

The first option works best on dual-screen devices like Surface Duo, where certain gestures are needed to change app display state. Our helper methods use the swipe method from the UiAutomator testing framework to simulate gestures like spanning, unspanning, switching, and closing apps. The animation below shows a UI test from our dual-screen experience example that performs a spanning swipe:

Animation of the "openProductsInDualLandscapeMode" test running on the Surface Duo emulator, where the dual-screen experience example is spanned and then the device is rotated before running the test

Figure 1. Animation of the openProductsInDualLandscapeMode test

The second option works on all kinds of foldables, so we would recommend using this approach to make sure your apps work well on many devices. Our helper methods use the Jetpack Window Manager testing artifact to send mock folding features to a test rule’s activity. The animation below shows a UI test from our Compose NavigationRail sample that simulates a vertical folding feature:

Animation of the "app_verticalFold_testPlaceholderViewAppearsOnStart" test running on the Surface Duo emulator, where the Compose NavRail sample opens in the left pane and then a vertical folding feature is simulated before running the UI test

Figure 2. Animation of the app_verticalFold_testPlaceholderViewAppearsOnStart test

Samples

To see more examples of how to use the Test Kit, check out these resources:

Test Kit Utility

Samples that demonstrate this feature

CurrentActivityDelegate

Surface Duo SDK

DeviceModel & UiDeviceExtensions

Surface Duo SDK

Dual-screen experience example

ComposeTesting sample

FoldingVideo

PhotoEditor

Source Editor

TwoNote

FoldingFeatureHelper

Surface Duo Compose samples

ComposeTesting sample

ForceClick

Surface Duo SDK

ViewMatcher

Surface Duo SDK

WindowLayoutInfoConsumer

Surface Duo SDK

StringHelper

Surface Duo Compose samples

Resources and feedback

Check out the Surface Duo developer documentation and past blog posts for links and details on all our samples. You can find our samples on GitHub

If you have any questions about the Test Kit, or would like to tell us about your apps, use the feedback forum or message us on Twitter @surfaceduodev

Finally, please join us on Twitch on Friday 25th March at 11am Pacific time to discuss foldable app testing.

0 comments

Comments are closed. Login to edit/delete your existing comments