Foldable devices have unique features and capabilities that require specialized testing. Test your app on small and large screen foldables, with the devices folded and unfolded, in portrait and landscape orientations, in tabletop and book postures, and in multi-window mode. See the Large screen app quality guidelines for more information.
FoldingFeature
The Jetpack WindowManager library notifies your app when the posture of a foldable device has changed so you can modify the app's layout.
The window-testing
artifact includes the
WindowLayoutInfoPublisherRule
JUnit4 rule which enables you to publish a custom
WindowInfoLayout
to
simulate a FoldingFeature
in tests.
To test for the status of a folding feature, first define a test class and the testing rules:
Kotlin
import androidx.window.layout.FoldingFeature.Orientation.Companion.HORIZONTAL import androidx.window.layout.FoldingFeature.Orientation.Companion.VERTICAL import androidx.window.layout.FoldingFeature.State.Companion.FLAT import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED import androidx.window.testing.layout.FoldingFeature import androidx.window.testing.layout.TestWindowLayoutInfo import androidx.window.testing.layout.WindowLayoutInfoPublisherRule @RunWith(AndroidJUnit4::class) class DisplayFeaturesActivityTest { private val activityRule = ActivityScenarioRule(DisplayFeaturesActivity::class.java) private val publisherRule = WindowLayoutInfoPublisherRule() @get:Rule val testRule: TestRule init { testRule = RuleChain.outerRule(publisherRule).around(activityRule) } @Test myTest() { // TODO } }
Java
import static androidx.window.layout.FoldingFeature.Orientation.HORIZONTAL; import static androidx.window.layout.FoldingFeature.Orientation.VERTICAL; import static androidx.window.layout.FoldingFeature.State.FLAT; import static androidx.window.layout.FoldingFeature.State.HALF_OPENED; import static androidx.window.testing.layout.DisplayFeatureTesting.createFoldingFeature; import static androidx.window.testing.layout.WindowLayoutInfoTesting.createWindowLayoutInfo; import androidx.window.layout.FoldingFeature; import androidx.window.layout.WindowLayoutInfo; import androidx.window.testing.layout.WindowLayoutInfoPublisherRule; @RunWith(AndroidJUnit4.class) public class DisplayFeaturesActivityJavaTest { private WindowLayoutInfoPublisherRule publisherRule = new WindowLayoutInfoPublisherRule(); @Rule public TestRule testRule; public DisplayFeaturesActivityJavaTest() { testRule = RuleChain.outerRule(publisherRule).around(activityRule); }; @Test public void myTest() { // TODO } }
Next you can simulate a folding feature, such as a half-opened foldable screen with a centered horizontal fold of zero width:
Kotlin
val feature = FoldingFeature( activity = activity, state = HALF_OPENED, orientation = HORIZONTAL) val expected = TestWindowLayoutInfo(listOf(feature))
Java
FoldingFeature feature = createFoldingFeature( activity, -1, 0, HALF_OPENED, HORIZONTAL); WindowLayoutInfo expected = createWindowLayoutInfo( Collections.singletonList(feature) );
Then, use the WindowLayoutInfoPublisherRule
to publish the custom
WindowLayoutInfo
:
Kotlin
@Test myTest() { ... publisherRule.overrideWindowLayoutInfo(expected) ... }
Java
@Test public void myTest() { ... publisherRule.overrideWindowLayoutInfo(expected); ... }
Finally, check whether the activity layout behaves as expected using the available Espresso matchers.
The following example simulates a FoldingFeature
with a
HALF_OPENED
vertical hinge in the screen’s center, then uses a matcher to check whether the
layout is the one expected:
Kotlin
@Test fun testDeviceOpen_Vertical() { activityRule.scenario.onActivity { activity -> val feature = FoldingFeature( activity = activity, state = HALF_OPENED, orientation = VERTICAL) val expected = TestWindowLayoutInfo(listOf(feature)) publisherRule.overrideWindowLayoutInfo(expected) } // Checks that start_layout is on the left of end_layout with a vertical folding feature. onView(withId(R.id.start_layout)) .check(isCompletelyLeftOf(withId(R.id.end_layout))) }
Java
@Test public void testDeviceOpen_Vertical() { activityRule .getScenario() .onActivity( activity -> { FoldingFeature feature = createFoldingFeature( activity, -1, 0, HALF_OPENED, VERTICAL); WindowLayoutInfo expected = createWindowLayoutInfo( Collections.singletonList(feature) ); publisherRule.overrideWindowLayoutInfo(expected); }); // Checks that start_layout is on the left of end_layout with a vertical folding feature. onView(withId(R.id.start_layout)) .check(isCompletelyLeftOf(withId(R.id.end_layout))); }
Configuration changes
If your app handles configuration changes programmatically with the onConfigurationChanged()
callback method, verify that the app responds promptly to configuration changes,
especially device rotation between portrait and landscape orientations.
To ensure your app is notified of orientation and display size changes, specify the following configuration settings in the activity:configChanges
manifest element:
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"