Episode ini membangun kepercayaan pada UI: unit testing composable, UI tests dengan Compose testing framework, assertions berbasis semantics dan test tags, serta integration testing dari UI ke lapisan data.

UI adalah bagian aplikasi yang paling sering berubah dan paling mudah rusak. Episode 14 membekali kalian dengan cara menguji Compose sehingga perubahan UI tidak lagi menakutkan: dari unit test composable sederhana sampai integration test yang menghubungkan UI dengan data.
Kekuatan testing Compose ada di Semantics API yang kalian pelajari di episode 13. Test berinteraksi dengan node semantics — cara yang sama TalkBack melihat aplikasi — sehingga test lebih realistis daripada mencari view berdasarkan ID.
Episode 14 ini meliputi setup test, unit testing, assertions berbasis semantics, test tags, dan integration testing.
Compose menyediakan library test khusus. Tambahkan di build Gradle:
androidTestImplementation(platform("androidx.compose:compose-bom:2024.12.01"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
testImplementation("junit:junit:4.13.2")ui-test-junit4 menyediakan createComposeRule, dan ui-test-manifest memungkinkan menjalankan test UI di debug build. Konfigurasi testOptions untuk animasi tidak perlu disetel — Compose test mematikan animasi secara otomatis.
Rule createComposeRule menyediakan lingkungan komposisi untuk test. Kalian bisa meng-set konten, menindaklanjuti interaksi, dan menegaskan state:
@RunWith(AndroidJUnit4::class)
class PenghitungTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun tombolMenambahAngka() {
composeRule.setContent {
Penghitung()
}
composeRule.onNodeWithText("Ditekan 0 kali").assertIsDisplayed()
composeRule.onNodeWithText("Tambah").performClick()
composeRule.onNodeWithText("Ditekan 1 kali").assertIsDisplayed()
}
}onNodeWithText(...) mencari node berdasarkan teks, performClick() menindaklanjuti klik, dan assertIsDisplayed() memverifikasi hasil. Test ini berjalan di emulator atau perangkat.
Compose test menyediakan banyak matcher: onNodeWithText, onNodeWithTag, onNodeWithContentDescription, dan assertion seperti assertIsDisplayed, assertExists, assertTextEquals:
composeRule.onNodeWithText("Kirim").assertIsEnabled()
composeRule.onNodeWithContentDescription("Keranjang").assertExists()
composeRule.onNodeWithText("Pesan").assertIsSelected()onNodeWithContentDescription("Keranjang") memakai deskripsi dari episode 13 — bukti bahwa accessibility dan testing berbagi lapisan semantics yang sama.
Terkadang teks atau deskripsi berubah karena lokalisasi. Gunakan test tags sebagai anchor yang stabil:
Card(
modifier = Modifier.testTag("kartu_produk_utama")
) {
Text("Produk Unggulan")
}composeRule.onNodeWithTag("kartu_produk_utama").assertIsDisplayed()Modifier.testTag("kartu_produk_utama") memberi identitas yang tidak terpengaruh terjemahan. onNodeWithTag memakai tag itu di test — kombinasi ideal untuk daftar yang panjang atau teks dinamis.
Untuk LazyColumn, node yang belum di-render tidak ada di tree. Geser dulu sebelum menegaskan:
composeRule.onNodeWithTag("daftar_produk").performScrollToIndex(50)
composeRule.onNodeWithText("Produk 50").assertIsDisplayed()performScrollToIndex(50) menggulir list ke indeks sebelum assertion. Lazy list hanya merender yang terlihat — prinsip yang sama dengan yang kalian pelajari di episode 9.
Integration test menggabungkan UI asli dengan data nyata atau fake:
@Test
fun loginGagalMenampilkanError() {
composeRule.setContent {
LoginScreen(viewModel = fakeLoginViewModel())
}
composeRule.onNodeWithTag("field_email").performTextInput("salah")
composeRule.onNodeWithTag("field_password").performTextInput("123")
composeRule.onNodeWithText("Masuk").performClick()
composeRule.onNodeWithText("Email tidak valid").assertIsDisplayed()
}fakeLoginViewModel menggantikan ViewModel asli sehingga test fokus pada UI, bukan jaringan. Pola fake ini menjaga test tetap cepat dan deterministik.
Jalankan semua UI test dari terminal:
./gradlew :app:connectedDebugAndroidTest./gradlew :app:connectedDebugAndroidTest menjalankan test di perangkat atau emulator yang terhubung. Hasilnya bisa dilihat di laporan HTML dan XML yang dihasilkan Gradle.
Episode 14 membangun kepercayaan pada UI: setup dependency test, unit test dengan createComposeRule, assertions berbasis semantics, test tags sebagai anchor yang stabil, pengujian lazy list, dan integration test dengan ViewModel fake.
Inti yang harus dibawa pulang:
Di episode 15 selanjutnya kita akan membahas performance optimization — meminimalkan recomposition, penggunaan remember dan derivedStateOf yang tepat, kunci stabil, serta benchmarking dan debugging performa UI.