Общие шаблоны

Вы можете протестировать свое приложение Compose, используя проверенные подходы и шаблоны.

Тест в изоляции

ComposeTestRule позволяет вам начать действие, отображающее любой компонуемый элемент: ваше полное приложение, один экран или небольшой элемент. Также хорошей практикой является проверка того, что ваши компонуемые элементы правильно инкапсулированы и работают независимо, что позволяет проводить более простое и целенаправленное тестирование пользовательского интерфейса.

Это не значит, что вам следует создавать только модульные тесты пользовательского интерфейса. Тесты пользовательского интерфейса, охватывающие более крупные части вашего пользовательского интерфейса, также очень важны.

Получите доступ к активности и ресурсам после настройки собственного контента.

Часто вам нужно установить тестируемое содержимое с помощью composeTestRule.setContent , а также вам нужно получить доступ к ресурсам активности, например, чтобы подтвердить, что отображаемый текст соответствует ресурсу строки. Однако вы не можете вызвать setContent для правила, созданного с помощью createAndroidComposeRule() , если активность уже вызывает его.

Распространенным шаблоном для достижения этой цели является создание AndroidComposeTestRule с использованием пустой активности, например 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()
    }
}

Обратите внимание, что ComponentActivity необходимо добавить в файл AndroidManifest.xml вашего приложения. Включите это, добавив эту зависимость в ваш модуль:

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

Пользовательские свойства семантики

Вы можете создать пользовательские свойства семантики , чтобы предоставить информацию для тестов. Для этого определите новый SemanticsPropertyKey и сделайте его доступным с помощью SemanticsPropertyReceiver .

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

Теперь используйте это свойство в модификаторе semantics :

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

В тестах используйте SemanticsMatcher.expectValue для подтверждения значения свойства:

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

Проверить состояние восстановления

Проверьте, что состояние элементов Compose правильно восстанавливается при повторном создании активности или процесса. Выполняйте такие проверки, не полагаясь на повторное создание активности с помощью класса StateRestorationTester .

Этот класс позволяет вам имитировать воссоздание компонуемого. Он особенно полезен для проверки реализации 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.
    }
}

Тестируйте различные конфигурации устройств

Приложения Android должны адаптироваться ко многим меняющимся условиям: размерам окон, локали, размерам шрифтов, темным и светлым темам и т. д. Большинство этих условий выводятся из значений на уровне устройства, контролируемых пользователем и предоставляемых текущим экземпляром Configuration . Тестирование различных конфигураций непосредственно в тесте затруднено, поскольку тест должен настраивать свойства на уровне устройства.

DeviceConfigurationOverride — это API, предназначенный только для тестирования, который позволяет моделировать различные конфигурации устройств локализованным способом для тестируемого содержимого @Composable .

Сопутствующий объект DeviceConfigurationOverride имеет следующие функции расширения, которые переопределяют свойства конфигурации на уровне устройства:

Чтобы применить определенное переопределение, заключите тестируемое содержимое в вызов функции верхнего уровня DeviceConfigurationOverride() , передав применяемое переопределение в качестве параметра.

Например, следующий код применяет переопределение DeviceConfigurationOverride.ForcedSize() для локального изменения плотности, заставляя компонуемый объект MyScreen отображаться в большом альбомном окне, даже если устройство, на котором выполняется тест, напрямую не поддерживает этот размер окна:

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

Чтобы применить несколько переопределений одновременно, используйте DeviceConfigurationOverride.then() :

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

Дополнительные ресурсы

  • Тестирование приложений на Android : главная целевая страница тестирования Android предоставляет более широкий обзор основ и методов тестирования.
  • Основы тестирования : узнайте больше об основных концепциях тестирования приложений Android.
  • Локальные тесты : вы можете запустить некоторые тесты локально, на своей рабочей станции.
  • Инструментированные тесты : Хорошей практикой является также запуск инструментированных тестов. То есть тестов, которые запускаются непосредственно на устройстве.
  • Непрерывная интеграция : Непрерывная интеграция позволяет интегрировать ваши тесты в конвейер развертывания.
  • Тестируйте разные размеры экранов : поскольку пользователям доступно множество устройств, вам следует тестировать экраны разных размеров.
  • Espresso : хотя знание Espresso и предназначено для пользовательских интерфейсов на основе View, оно все равно может быть полезно для некоторых аспектов тестирования Compose.