Testowanie pod kątem zmian w konfiguracji ekranu za pomocą interfejsu Espresso Device API

Użyj interfejsu Espresso Device API, aby przetestować aplikację, gdy urządzenie przechodzi typowe zmiany konfiguracji, takie jak obrót i rozkładanie ekranu. Interfejs Espresso Device API to zalecane narzędzie do wykonywania działań na poziomie urządzenia wraz z regułami testowania w Jetpack Compose. Jeśli dopiero zaczynasz pisać testy interfejsu Jetpack Compose, zapoznaj się z artykułem Testowanie układu Compose.

Interfejs Espresso Device API umożliwia wywoływanie zmian konfiguracji na urządzeniu wirtualnym i synchroniczne wykonywanie testów, dzięki czemu w danym momencie wykonywana jest tylko jedna czynność w interfejsie lub jedno sprawdzenie, a wyniki testów są bardziej wiarygodne. Jeśli dopiero zaczynasz pisać testy interfejsu za pomocą Espresso, zapoznaj się z jego dokumentacją.

Aby korzystać z interfejsu Espresso Device API, musisz mieć:

  • Android Studio Iguana lub nowszy
  • Wtyczka Androida do obsługi Gradle w wersji 8.3 lub nowszej
  • Android Emulator w wersji 33.1.10 lub nowszej
  • wirtualne urządzenie z Androidem z poziomem interfejsu API 24 lub nowszym,

Konfigurowanie projektu na potrzeby interfejsu Espresso Device API

Aby skonfigurować projekt tak, aby obsługiwał interfejs Espresso Device API, wykonaj te czynności:

  1. Aby test mógł przekazywać polecenia do urządzenia testowego, dodaj do pliku manifestu w androidTest zbiorze źródeł wymagane uprawnienia sieciowe:

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

    Jeśli test jest kierowany na Androida 17 (API na poziomie 37) lub nowszego, musisz też zadeklarować uprawnienie ACCESS_LOCAL_NETWORK:

      <uses-permission android:name="android.permission.ACCESS_LOCAL_NETWORK" />
    
  2. Włącz flagę eksperymentalną enableEmulatorControl w pliku gradle.properties:

      android.experimental.androidTest.enableEmulatorControl=true
    
  3. Włącz opcję emulatorControl w skrypcie kompilacji na poziomie modułu:

    Kotlin

      testOptions {
        emulatorControl {
          enable = true
        }
      }
      

    Dynamiczny

      testOptions {
        emulatorControl {
          enable = true
        }
      }
      
  4. W skrypcie kompilacji na poziomie modułu zaimportuj do projektu bibliotekę Espresso Device:

    Kotlin

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

    Dynamiczny

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

Testowanie pod kątem typowych zmian konfiguracji

Interfejs Espresso Device API ma wiele stanów orientacji ekranu i stanów składania, których możesz używać do wywoływania zmian konfiguracji urządzenia. Poniższe przykłady pokazują, jak wywołać te stany urządzenia i zweryfikować wynikające z nich zmiany w interfejsie za pomocą reguł testowych Compose.

Testowanie obrotu ekranu

Aby przetestować obrót ekranu, możesz użyć klasy ScreenOrientationRule, aby zdefiniować orientację urządzenia podczas testu.

Oto przykład testowania działania aplikacji po obróceniu ekranu urządzenia:

  1. Najpierw zdefiniuj regułę testu Compose i użyj klasy ScreenOrientationRule, aby ustawić urządzenie w spójnym stanie początkowym (np. w trybie pionowym):

    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)
    }
    

    Jeśli test jest kierowany na Androida 17 (API na poziomie 37) lub nowszego, interfejs Espresso Device API wymaga uprawnienia ACCESS_LOCAL_NETWORK. Zanim reguła ScreenOrientationRule zostanie uruchomiona, musisz upewnić się, że to uprawnienie zostało przyznane. Użyj RuleChain JUnit, aby najpierw uruchomić GrantPermissionRule rule:

    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. Utwórz test, który podczas wykonywania testu ustawia urządzenie w orientacji poziomej:

    @Test
    fun myRotationTest() {
      ...
      // Sets the device to landscape orientation during test execution.
      onDevice().setScreenOrientation(ScreenOrientation.LANDSCAPE)
      ...
    }
    
  3. Po obróceniu ekranu użyj composeTestRule, aby sprawdzić, czy komponenty kompozycyjne dostosowują się do nowego stanu zgodnie z oczekiwaniami.

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

Testowanie na urządzeniach z rozkładanym ekranem

Oto przykład testowania, co się stanie z aplikacją, gdy będzie ona działać na urządzeniu składanym i ekran się rozłoży:

  1. Najpierw przetestuj urządzenie w stanie złożonym, dzwoniąc pod numer onDevice().setClosedMode(). Sprawdź, czy komponenty kompozycyjne dostosowują się do wąskiego ekranu.

    @Test
    fun myUnfoldedTest() {
      onDevice().setClosedMode()
      composeTestRule.onNodeWithTag("BottomBar").assertIsDisplayed()
      composeTestRule.onNodeWithTag("NavRail").assertDoesNotExist()
      ...
    }
    
  2. Aby przejść do stanu całkowicie rozłożonego, wywołaj onDevice().setFlatMode(). Sprawdź, czy komponenty kompozycyjne dostosowują się do rozszerzonej klasy rozmiaru.

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

Określanie, jakich urządzeń wymagają testy

Jeśli przeprowadzisz test, który wykonuje czynności składania na urządzeniu, które nie jest składane, test prawdopodobnie się nie powiedzie. Aby uruchomić tylko testy odpowiednie dla urządzenia, na którym są przeprowadzane, użyj adnotacji @RequiresDeviceMode. Program do uruchamiania testów automatycznie pomija testy na urządzeniach, które nie obsługują testowanej konfiguracji. Regułę dotyczącą wymagań urządzenia możesz dodać do każdego testu lub do całej klasy testów.

Jeśli na przykład chcesz określić, że test ma być przeprowadzany tylko na urządzeniach, które obsługują rozkładanie do płaskiej konfiguracji, dodaj do testu ten @RequiresDeviceModekod:

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