Anda dapat menguji aplikasi Compose dengan pendekatan dan pola yang sudah mapan.
Pengujian secara terpisah
ComposeTestRule memungkinkan Anda memulai aktivitas yang menampilkan composable apa pun:
aplikasi lengkap, satu layar, atau elemen kecil. Selain itu, merupakan praktik
yang baik untuk memeriksa apakah composable Anda dienkapsulasi dengan benar dan berfungsi
secara independen, sehingga memungkinkan pengujian UI yang lebih mudah dan lebih terfokus.
Ini tidak berarti Anda hanya akan membuat pengujian UI unit. Pengujian UI yang mencakup sebagian besar UI yang ada juga sangat penting.
Mengakses aktivitas dan resource setelah menetapkan konten Anda sendiri
Sering kali Anda perlu menetapkan konten yang sedang diuji menggunakan
composeTestRule.setContent dan juga perlu mengakses resource aktivitas, misalnya
untuk menyatakan bahwa teks yang ditampilkan cocok dengan resource string. Namun, Anda
tidak dapat memanggil setContent pada aturan yang dibuat dengan createAndroidComposeRule() jika
aktivitas sudah memanggilnya.
Pola umum untuk melakukannya adalah dengan membuat AndroidComposeTestRule menggunakan
aktivitas kosong seperti 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()
}
}
Perlu diperhatikan bahwa ComponentActivity harus ditambahkan ke file
AndroidManifest.xml aplikasi Anda. Aktifkan dengan menambahkan dependensi ini ke
modul:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
Properti semantik kustom
Anda dapat membuat properti semantik kustom untuk mengekspos informasi ke pengujian.
Untuk melakukannya, tentukan SemanticsPropertyKey baru dan sediakan menggunakan
SemanticsPropertyReceiver.
// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey
Sekarang, gunakan properti tersebut dalam pengubah semantics:
val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
modifier = Modifier.semantics { pickedDate = datePickerValue }
)
Dari pengujian, gunakan SemanticsMatcher.expectValue untuk menyatakan nilai
properti:
composeTestRule
.onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
.assertExists()
Memverifikasi pemulihan status
Verifikasi bahwa status elemen Compose Anda dipulihkan dengan benar saat
aktivitas atau proses dibuat ulang. Lakukan pemeriksaan tersebut tanpa mengandalkan
pembuatan ulang aktivitas dengan class StateRestorationTester.
Class ini memungkinkan Anda menyimulasikan pembuatan ulang composable. Hal ini sangat berguna untuk memverifikasi penerapan 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.
}
}
Menguji berbagai konfigurasi perangkat
Aplikasi Android harus beradaptasi dengan banyak kondisi yang berubah: ukuran jendela, lokalitas,
ukuran font, tema gelap dan terang, dan banyak lagi. Sebagian besar kondisi ini berasal dari nilai tingkat perangkat yang dikontrol oleh pengguna dan diekspos dengan instance Configuration saat ini. Menguji berbagai konfigurasi
secara langsung dalam pengujian sulit dilakukan karena pengujian harus mengonfigurasi properti
tingkat perangkat.
DeviceConfigurationOverride adalah API khusus pengujian yang memungkinkan Anda menyimulasikan
konfigurasi perangkat yang berbeda secara terlokalisasi untuk konten @Composable
yang sedang diuji.
Objek pendamping DeviceConfigurationOverride memiliki fungsi ekstensi berikut, yang menggantikan properti konfigurasi tingkat perangkat:
DeviceConfigurationOverride.DarkMode(): Menggantikan sistem ke tema gelap atau tema terang.DeviceConfigurationOverride.FontScale(): Mengganti skala font sistem.DeviceConfigurationOverride.FontWeightAdjustment(): Menggantikan penyesuaian ketebalan font sistem.DeviceConfigurationOverride.ForcedSize(): Memaksa jumlah ruang tertentu terlepas dari ukuran perangkat.DeviceConfigurationOverride.LayoutDirection(): Menggantikan arah tata letak (kiri-ke-kanan atau kanan-ke-kiri).DeviceConfigurationOverride.Locales(): Mengganti locale.DeviceConfigurationOverride.RoundScreen(): Menggantikan jika layar bulat.
Untuk menerapkan penggantian tertentu, bungkus konten yang sedang diuji dalam panggilan ke fungsi level teratas
DeviceConfigurationOverride(), dengan meneruskan penggantian
yang akan diterapkan sebagai parameter.
Misalnya, kode berikut menerapkan penggantian
DeviceConfigurationOverride.ForcedSize() untuk mengubah kepadatan
secara lokal, sehingga composable MyScreen dirender di jendela lanskap besar, meskipun perangkat tempat pengujian dijalankan tidak mendukung ukuran jendela
tersebut secara langsung:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp)) ) { MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping. } }
Untuk menerapkan beberapa penggantian secara bersamaan, gunakan
DeviceConfigurationOverride.then():
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.FontScale(1.5f) then DeviceConfigurationOverride.FontWeightAdjustment(200) ) { Text(text = "text with increased scale and weight") } }
Penanganan kegagalan kustom dalam pengujian
Proses debug pengujian UI sering kali memerlukan pemeriksaan status layar dan hierarki komposisi saat pernyataan gagal.
Compose menyediakan pipeline penanganan kegagalan native untuk menyederhanakan diagnostik. Anda dapat otomatis mengambil screenshot dan hierarki UI saat terjadi kegagalan, atau mendaftarkan pengendali kustom untuk meneruskan telemetri error ke alat eksternal.
Mengonfigurasi penanganan kegagalan
Untuk mengonfigurasi penanganan kegagalan, teruskan objek TestFailurePolicy ke
ComposeUiTestConfig.
Merekam artefak kegagalan bawaan
Untuk mengambil screenshot dan hierarki UI saat terjadi kegagalan uji, tetapkan properti
screenshotCaptureMode dan uiHierarchyCaptureMode di
TestFailurePolicy.
class MyComposeTest { private val customConfig = ComposeUiTestConfig( failurePolicy = TestFailurePolicy( screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled, uiHierarchyCaptureMode = TestFailurePolicy.CaptureMode.Enabled ) ) @Test fun myFirstTest() = runComposeUiTest(config = customConfig) { // ... } }
Menggunakan pengendali kegagalan kustom
Untuk menentukan perilaku kustom untuk kegagalan pengujian, tambahkan
TestFailureHandler ke daftar failureHandlers. Setiap handler
menerima objek FailureContext yang berisi error asli dan
daftar artefak yang dihasilkan oleh handler pipeline sebelumnya.
class MyComposeTestWithHandler { private val customConfig = ComposeUiTestConfig( failurePolicy = TestFailurePolicy( screenshotCaptureMode = TestFailurePolicy.CaptureMode.Enabled, failureHandlers = listOf( TestFailureHandler { context -> val screenshot = context.artifacts.firstOrNull { it.type == FailureArtifact.Type.Screenshot } // ... } ) ) ) @get:Rule val rule = createComposeRule(config = customConfig) // ... }
Mengonfigurasi perekaman untuk seluruh suite pengujian
Anda dapat mengaktifkan pengambilan artefak kegagalan untuk seluruh suite pengujian dengan meneruskan argumen peluncur instrumentasi dalam file build.gradle modul Anda. Hal ini
menghilangkan kebutuhan untuk memperbarui file uji individual.
// build.gradle.kts
android {
defaultConfig {
// ...
testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isUiHierarchyCaptureEnabled"] = "true"
testInstrumentationRunnerArguments["androidx.compose.ui.test.failure.isScreenshotCaptureEnabled"] = "true"
}
}
Prioritas konfigurasi
Framework mengevaluasi argumen peluncur tingkat suite dan TestFailurePolicy lokal:
- Jika Anda secara eksplisit menyetel mode ke
CaptureMode.Enabled/DisableddifailurePolicypengujian, hal ini akan menggantikan argumen runner. - Jika Anda menyetel mode ke
CaptureMode.Unspecified(atau membiarkanfailurePolicysebagainull), framework akan kembali ke argumen peluncur.
Referensi Tambahan
- Menguji aplikasi di Android: Halaman landing utama pengujian Android memberikan gambaran yang lebih luas tentang dasar-dasar dan teknik pengujian.
- Dasar-dasar pengujian: Pelajari lebih lanjut konsep inti di balik pengujian aplikasi Android.
- Pengujian lokal: Anda dapat menjalankan beberapa pengujian secara lokal, di workstation Anda sendiri.
- Pengujian berinstrumen: Sebaiknya jalankan juga pengujian berinstrumen. Artinya, pengujian yang dijalankan langsung di perangkat.
- Continuous integration: Continuous integration memungkinkan Anda mengintegrasikan pengujian ke dalam pipeline deployment.
- Uji berbagai ukuran layar: Dengan banyaknya perangkat yang tersedia bagi pengguna, Anda harus menguji berbagai ukuran layar.
- Espresso: Meskipun ditujukan untuk UI berbasis Tampilan, pengetahuan Espresso masih dapat membantu untuk beberapa aspek pengujian Compose.