Вы можете протестировать свое приложение 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.DarkMode()
: переопределяет систему на темную или светлую тему. -
DeviceConfigurationOverride.FontScale()
: переопределяет масштаб системного шрифта . -
DeviceConfigurationOverride.FontWeightAdjustment()
: переопределяет настройку веса системного шрифта. -
DeviceConfigurationOverride.ForcedSize()
: принудительно выделяет определенный объем пространства независимо от размера устройства. -
DeviceConfigurationOverride.LayoutDirection()
: переопределяет направление макета (слева направо или справа налево). -
DeviceConfigurationOverride.Locales()
: переопределяет языковой стандарт . -
DeviceConfigurationOverride.RoundScreen()
: переопределяет, если экран круглый .
Чтобы применить определенное переопределение, оберните тестируемое содержимое вызовом функции верхнего уровня 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 предназначены для пользовательских интерфейсов на основе представлений, они все же могут быть полезны для некоторых аспектов тестирования Compose.