Mit der Espresso Device API auf Änderungen der Bildschirmkonfiguration testen

Mit der Espresso Device API können Sie Ihre App testen, wenn das Gerät häufigen Konfigurationsänderungen unterzogen wird, z. B. Drehen und Aufklappen des Displays. Die Espresso Device API ist das empfohlene Tool zum Ausführen von Aktionen auf Geräteebene zusammen mit Ihren Jetpack Compose-Testregeln. Wenn Sie noch keine UI-Tests für Jetpack Compose geschrieben haben, lesen Sie den Artikel Compose-Layout testen.

Mit der Espresso Device API können Sie Konfigurationsänderungen auf einem virtuellen Gerät auslösen und Ihre Tests synchron ausführen. So wird jeweils nur eine UI-Aktion oder ‑Assertion ausgeführt und Ihre Testergebnisse sind zuverlässiger. Wenn Sie noch keine UI-Tests mit Espresso geschrieben haben, finden Sie hier die Dokumentation.

Für die Verwendung der Espresso Device API benötigen Sie Folgendes:

  • Android Studio Iguana oder höher
  • Android-Gradle-Plug-in 8.3 oder höher
  • Android Emulator 33.1.10 oder höher
  • Virtuelles Android-Gerät mit API-Level 24 oder höher

Projekt für die Espresso Device API einrichten

So richten Sie Ihr Projekt für die Unterstützung der Espresso Device API ein:

  1. Damit der Test Befehle an das Testgerät übergeben kann, fügen Sie der Manifestdatei im Quellsatz androidTest die erforderlichen Netzwerkberechtigungen hinzu:

      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    

    Wenn Ihr Test auf Android 17 (API‑Level 37) oder höher ausgerichtet ist, müssen Sie auch die Berechtigung ACCESS_LOCAL_NETWORK deklarieren:

      <uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK" />
    
  2. Aktivieren Sie das experimentelle Flag enableEmulatorControl in der Datei gradle.properties:

      android.experimental.androidTest.enableEmulatorControl=true
    
  3. Aktivieren Sie die Option emulatorControl im Build-Skript auf Modulebene:

    Kotlin

      testOptions {
        emulatorControl {
          enable = true
        }
      }
      

    Groovy

      testOptions {
        emulatorControl {
          enable = true
        }
      }
      
  4. Importieren Sie die Espresso Device-Bibliothek in das Build-Skript auf Modulebene:

    Kotlin

    dependencies {
      androidTestImplementation("androidx.test.espresso:espresso-device:1.1.0")
    }

    Groovy

    dependencies {
      androidTestImplementation 'androidx.test.espresso:espresso-device:1.1.0'
    }

Häufige Konfigurationsänderungen testen

Die Espresso Device API bietet mehrere Bildschirmorientierungen und faltbare Zustände, mit denen Sie Änderungen an der Gerätekonfiguration auslösen können. Die folgenden Beispiele zeigen, wie Sie diese Gerätestatus auslösen und die resultierenden UI-Änderungen mit Compose-Testregeln überprüfen.

Auf Bildschirmdrehung testen

Um die Bildschirmdrehung zu testen, können Sie die ScreenOrientationRule-Klasse verwenden, um die Geräteausrichtung während des Tests zu definieren.

Hier ist ein Beispiel dafür, wie Sie testen können, was mit Ihrer App passiert, wenn sich das Display des Geräts dreht:

  1. Definieren Sie zuerst Ihre Compose-Testregel und verwenden Sie die Klasse ScreenOrientationRule, um das Gerät in einen konsistenten Startzustand zu versetzen (z. B. Hochformat):

    import androidx.compose.ui.test.assertIsDisplayed
    import androidx.compose.ui.test.assertDoesNotExist
    import androidx.compose.ui.test.junit4.createComposeRule
    import androidx.compose.ui.test.onNodeWithTag
    import androidx.test.espresso.device.EspressoDevice.onDevice
    import androidx.test.espresso.device.action.ScreenOrientation
    import androidx.test.espresso.device.rules.ScreenOrientationRule
    import org.junit.Rule
    import org.junit.Test
    
    class MyConfigurationTest {
    
        // 1. Define the Compose test rule
        @get:Rule
        val composeTestRule = createComposeRule()
    
        // 2. Define the Espresso Device rule for a consistent starting state
        @get:Rule
        val screenOrientationRule = ScreenOrientationRule(ScreenOrientation.PORTRAIT)
    }
    

    Wenn Ihr Test auf Android 17 (API‑Level 37) oder höher ausgerichtet ist, ist für die Espresso Device API die Berechtigung ACCESS_LOCAL_NETWORK erforderlich. Sie müssen dafür sorgen, dass diese Berechtigung erteilt wird, bevor die ScreenOrientationRule-Regel ausgeführt wird. Verwenden Sie RuleChain von JUnit, um die GrantPermissionRule-Regel zuerst auszuführen:

    import androidx.test.rule.GrantPermissionRule
    import org.junit.rules.RuleChain
    
    class MyConfigurationTest {
        val grantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_LOCAL_NETWORK)
        val composeTestRule = createComposeRule()
        val screenOrientationRule = ScreenOrientationRule(ScreenOrientation.PORTRAIT)
    
        @get:Rule
        val chain = RuleChain
            .outerRule(grantPermissionRule)
            .around(composeTestRule)
            .around(screenOrientationRule)
    }
    
  2. Erstellen Sie einen Test, der das Gerät während der Testausführung ins Querformat versetzt:

    @Test
    fun myRotationTest() {
      ...
      // Sets the device to landscape orientation during test execution.
      onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)
      ...
    }
    
  3. Nachdem sich der Bildschirm gedreht hat, können Sie mit composeTestRule prüfen, ob sich Ihre komponierbaren Funktionen wie erwartet an den neuen Zustand anpassen.

    @Test
    fun myRotationTest() {
      ...
      // Sets the device to landscape orientation during test execution.
      onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)
      composeTestRule.onNodeWithTag("NavRail").assertIsDisplayed()
      composeTestRule.onNodeWithTag("BottomBar").assertDoesNotExist()
    }
    

Testen, ob das Display aufgeklappt wird

Hier ist ein Beispiel dafür, wie Sie testen können, was mit Ihrer App passiert, wenn sie auf einem faltbaren Gerät ausgeführt wird und der Bildschirm aufgeklappt wird:

  1. Testen Sie zuerst mit dem Gerät im zusammengeklappten Zustand, indem Sie onDevice().setClosedMode() aufrufen. Achten Sie darauf, dass sich Ihre Composables an die kompakte Bildschirmbreite anpassen.

    @Test
    fun myUnfoldedTest() {
      onDevice().setClosedMode()
      composeTestRule.onNodeWithTag("BottomBar").assertIsDisplayed()
      composeTestRule.onNodeWithTag("NavRail").assertDoesNotExist()
      ...
    }
    
  2. Rufen Sie onDevice().setFlatMode() auf, um in den vollständig aufgeklappten Zustand zu wechseln. Prüfen Sie, ob sich die Composables an die erweiterte Größenklasse anpassen.

    @Test
    fun myUnfoldedTest() {
      onDevice().setClosedMode()
      ...
      onDevice().setFlatMode()
      composeTestRule.onNodeWithTag("NavRail").assertIsDisplayed()
      composeTestRule.onNodeWithTag("BottomBar").assertDoesNotExist()
    }
    

Angeben, welche Geräte für Ihre Tests erforderlich sind

Wenn Sie einen Test ausführen, bei dem Faltvorgänge auf einem Gerät ausgeführt werden, das nicht faltbar ist, schlägt der Test wahrscheinlich fehl. Wenn Sie nur die Tests ausführen möchten, die für das aktuelle Gerät relevant sind, verwenden Sie die Annotation @RequiresDeviceMode. Der Test-Runner überspringt automatisch Tests auf Geräten, die die getestete Konfiguration nicht unterstützen. Sie können die Regel für Geräteanforderungen jedem Test oder einer ganzen Testklasse hinzufügen.

Wenn Sie beispielsweise festlegen möchten, dass ein Test nur auf Geräten ausgeführt werden soll, die das Aufklappen in eine flache Konfiguration unterstützen, fügen Sie Ihrem Test den folgenden @RequiresDeviceMode-Code hinzu:

@Test
@RequiresDeviceMode(mode = FLAT)
fun myUnfoldedTest() {
  ...
}