Belajar Jetpack Compose - Testing Compose UI
Episode 14 of 23

Belajar Jetpack Compose - Testing Compose UI

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.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

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.

Menyiapkan Dependency Test

Test Dependencies

Compose menyediakan library test khusus. Tambahkan di build Gradle:

KotlinDependency testing
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.

Unit Testing Composable

createComposeRule

Rule createComposeRule menyediakan lingkungan komposisi untuk test. Kalian bisa meng-set konten, menindaklanjuti interaksi, dan menegaskan state:

KotlinUnit test composable
@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.

Assertions Berbasis Semantics

Matcher dan Assertions

Compose test menyediakan banyak matcher: onNodeWithText, onNodeWithTag, onNodeWithContentDescription, dan assertion seperti assertIsDisplayed, assertExists, assertTextEquals:

KotlinAssertions semantics
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.

Test Tags untuk Seleksi Kuat

Test Tags Sebagai Anchor

Terkadang teks atau deskripsi berubah karena lokalisasi. Gunakan test tags sebagai anchor yang stabil:

KotlinTest tag
Card(
    modifier = Modifier.testTag("kartu_produk_utama")
) {
    Text("Produk Unggulan")
}
KotlinMemakai test tag
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.

Mengetes List Lazy

Untuk LazyColumn, node yang belum di-render tidak ada di tree. Geser dulu sebelum menegaskan:

KotlinTest lazy list
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 Testing

Menghubungkan UI dan Data

Integration test menggabungkan UI asli dengan data nyata atau fake:

KotlinIntegration test
@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.

Menjalankan Test

Jalankan semua UI test dari terminal:

Menjalankan androidTest
./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.

Penutup

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:

  • createComposeRule menyediakan lingkungan test untuk composable.
  • onNodeWithText dan performClick mensimulasikan interaksi nyata.
  • Semantics API menjadi fondasi test sekaligus aksesibilitas.
  • testTag memberi identitas yang kebal terhadap lokalisasi.
  • Lazy list perlu di-scroll sebelum itemnya bisa diassert.
  • Integration test memakai fake untuk menjaga kecepatan dan stabilitas.

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.

Belajar Jetpack Compose - Testing Compose UI | Belajar Jetpack Compose