잘 확립된 접근 방식과 패턴으로 Compose 앱을 테스트할 수 있습니다.
개별적으로 테스트
ComposeTestRule
을 사용하면 전체 애플리케이션, 단일 화면, 작은 요소 등 컴포저블을 표시하는 활동을 시작할 수 있습니다. 또한 컴포저블이 올바르게 캡슐화되어 있고 독립적으로 작동하는지 확인하는 것도 좋은 방법입니다. 그러면 더 쉽고 집중적인 UI 테스트가 가능합니다.
그렇다고 오직 단위 UI 테스트만 만들어야 한다는 의미는 아닙니다. UI의 더 큰 부분을 범위로 지정하는 UI 테스트도 매우 중요합니다.
자체 콘텐츠를 설정한 후 활동 및 리소스에 액세스
예를 들어 표시된 텍스트가 문자열 리소스와 일치하는지 어설션하기 위해 composeTestRule.setContent
를 사용하여 테스트 중인 콘텐츠를 설정해야 하고 활동 리소스에도 액세스해야 하는 경우가 종종 있습니다. 그러나 활동에서 이미 호출한 경우 createAndroidComposeRule()
로 만든 규칙에서 setContent
를 호출할 수 없습니다.
이를 위한 일반적인 패턴은 ComponentActivity
와 같은 빈 활동을 사용하여 AndroidComposeTestRule
을 만드는 것입니다.
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
는 테스트 중인 @Composable
콘텐츠에 맞게 현지화된 방식으로 다양한 기기 구성을 시뮬레이션할 수 있는 테스트 전용 API입니다.
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: 뷰 기반 UI를 위한 것이지만 Espresso 지식은 여전히 Compose 테스트의 일부 측면에 유용할 수 있습니다.