Typowe wzorce

Aplikację Compose możesz testować, stosując sprawdzone metody i wzorce.

Testowanie w odizolowaniu

ComposeTestRule pozwala rozpocząć aktywność wyświetlającą dowolną kompozycję: całą aplikację, pojedynczy ekran lub mały element. Dobrą praktyką jest też sprawdzenie, czy komponenty są prawidłowo zakapsułkowane i działają niezależnie, co ułatwia i ukierunkowuje testowanie interfejsu użytkownika.

Nie oznacza to, że musisz tworzyć tylko testy UI. Testy UI obejmujące większe części interfejsu są również bardzo ważne.

Po skonfigurowaniu własnych treści możesz uzyskać dostęp do aktywności i zasobów

Często trzeba ustawić treści testowane za pomocą funkcji composeTestRule.setContent. Trzeba też mieć dostęp do zasobów aktywności, na przykład do weryfikacji, czy wyświetlany tekst jest zgodny z zasobem ciągu znaków. Nie możesz jednak wywołać funkcji setContent w regułach utworzonych za pomocą funkcji createAndroidComposeRule(), jeśli funkcja ta jest już wywoływana przez aktywność.

Typowym sposobem na osiągnięcie tego celu jest utworzenie AndroidComposeTestRule za pomocą pustej czynności, np. ComponentActivity.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<ComponentActivity>()

    @Test
    fun myTest() {
        // Start the app
        composeTestRule.setContent {
            MyAppTheme {
                MainScreen(uiState = exampleUiState, /*...*/)
            }
        }
        val continueLabel = composeTestRule.activity.getString(R.string.next)
        composeTestRule.onNodeWithText(continueLabel).performClick()
    }
}

Pamiętaj, że ComponentActivity musi zostać dodany do pliku AndroidManifest.xml aplikacji. Aby to umożliwić, dodaj tę zależność do swojego modułu:

debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")

Właściwości semantyzacji niestandardowej

Możesz utworzyć niestandardowe właściwości semantyki, aby udostępnić informacje testom. Aby to zrobić, zdefiniuj nową wartość SemanticsPropertyKey i ustaw ją za pomocą elementu SemanticsPropertyReceiver.

// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey

Teraz użyj tej właściwości w modyfikatorze semantics:

val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
    modifier = Modifier.semantics { pickedDate = datePickerValue }
)

W testach użyj SemanticsMatcher.expectValue, aby określić wartość właściwości:

composeTestRule
    .onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
    .assertExists()

Weryfikacja przywrócenia stanu

Sprawdź, czy stan elementów Compose jest prawidłowo przywracany, gdy ponownie tworzysz aktywność lub proces. Wykonuj takie kontrole bez konieczności odtwarzania aktywności za pomocą klasy StateRestorationTester.

Ta klasa umożliwia symulowanie odtworzenia składanego. Jest to szczególnie przydatne do weryfikacji implementacji rememberSaveable.


class MyStateRestorationTests {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        restorationTester.setContent { MainScreen() }

        // TODO: Run actions that modify the state

        // Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()

        // TODO: Verify that state has been correctly restored.
    }
}

Testowanie różnych konfiguracji urządzeń

Aplikacje na Androida muszą dostosowywać się do wielu zmiennych warunków: rozmiarów okien, lokalizacji, rozmiarów czcionek, ciemnych i jasnych motywów itp. Większość z nich jest pochodna od wartości na poziomie urządzenia, które są kontrolowane przez użytkownika i wyświetlane w bieżącym wystąpieniu Configuration. Testowanie różnych konfiguracji bezpośrednio w ramach testu jest trudne, ponieważ test musi konfigurować właściwości na poziomie urządzenia.

DeviceConfigurationOverride to interfejs API przeznaczony tylko do testów, który umożliwia symulowanie różnych konfiguracji urządzeń w sposób zlokalizowany w przypadku testowanych treści @Composable.

Obiekt towarzyszący DeviceConfigurationOverride ma te funkcje rozszerzenia, które zastępują właściwości konfiguracji na poziomie urządzenia:

Aby zastosować konkretne zastąpienie, owiń treści, które mają być testowane, w wywołaniu do funkcji najwyższego poziomu DeviceConfigurationOverride(), przekazując zastąpienie jako parametr.

Na przykład ten kod stosuje zastąpienie DeviceConfigurationOverride.ForcedSize(), aby zmienić gęstość lokalnie, wymuszając renderowanie kompozytowego MyScreen w dużej panoramicznej ramce okna, nawet jeśli urządzenie, na którym działa test, nie obsługuje bezpośrednio tego rozmiaru okna:

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp))
    ) {
        MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping.
    }
}

Aby zastosować kilka zastąpień jednocześnie, użyj DeviceConfigurationOverride.then():

composeTestRule.setContent {
    DeviceConfigurationOverride(
        DeviceConfigurationOverride.FontScale(1.5f) then
            DeviceConfigurationOverride.FontWeightAdjustment(200)
    ) {
        Text(text = "text with increased scale and weight")
    }
}

Dodatkowe materiały

  • Testowanie aplikacji na Androida: główna strona z informacjami o testowaniu na Androida zawiera więcej informacji o podstawach i technikach testowania.
  • Podstawy testowania: dowiedz się więcej o podstawowych koncepcjach testowania aplikacji na Androida.
  • Testy lokalne: niektóre testy możesz przeprowadzać lokalnie na swoim komputerze.
  • Testy z instrumentacją: warto też przeprowadzać testy z instrumentacją. Chodzi o testy, które są wykonywane bezpośrednio na urządzeniu.
  • Tryb ciągłej integracji: tryb ciągłej integracji umożliwia zintegrowanie testów z potokiem wdrożeniowym.
  • Testowanie różnych rozmiarów ekranu: ze względu na dużą liczbę urządzeń dostępnych dla użytkowników, należy przeprowadzić testy na różnych rozmiarach ekranu.
  • Espresso: chociaż jest ono przeznaczone do interfejsów użytkownika opartych na widokach, wiedza o Espresso może być przydatna w niektórych aspektach testowania Compose.