Вы можете протестировать свое приложение 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 и предназначено для пользовательских интерфейсов на основе View, оно все равно может быть полезно для некоторых аспектов тестирования Compose.