Topik ini menjelaskan cara menyertakan API yang disediakan framework dalam pengujian yang mengevaluasi perilaku setiap fragmen.
Fragmen berfungsi sebagai penampung yang dapat digunakan kembali dalam aplikasi Anda, sehingga Anda dapat menyajikan tata letak antarmuka pengguna yang sama di berbagai aktivitas dan konfigurasi tata letak. Dengan keserbagunaannya, sangatlah penting untuk memvalidasi bahwa fragmen memberikan pengalaman yang konsisten dan efisien akan resource. Perhatikan hal berikut:
- Fragmen Anda tidak boleh bergantung pada induk aktivitas atau fragmen tertentu.
- Anda tidak boleh membuat hierarki tampilan fragmen kecuali jika fragmen tersebut terlihat oleh pengguna.
Untuk membantu menyiapkan kondisi dalam menjalankan pengujian, library
fragment-testing
AndroidX menyediakan class
FragmentScenario
untuk membuat fragmen dan mengubah
Lifecycle.State
.
Mendeklarasikan dependensi
Untuk menggunakan FragmentScenario
, tentukan artefak fragment-testing-manifest
di
file build.gradle
aplikasi menggunakan debugImplementation
, dan artefak fragment-testing
menggunakan androidTestImplementation
seperti yang ditampilkan dalam
contoh berikut:
Groovy
dependencies { def fragment_version = "1.8.2" debugImplementation "androidx.fragment:fragment-testing-manifest:$fragment_version" androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version" }
Kotlin
dependencies { val fragment_version = "1.8.2" debugImplementation("androidx.fragment:fragment-testing-manifest:$fragment_version") androidTestImplementation("androidx.fragment:fragment-testing:$fragment_version") }
Contoh pengujian di halaman ini menggunakan pernyataan dari library Espresso dan Truth. Untuk informasi tentang library pengujian dan pernyataan tersedia lainnya, lihat Menyiapkan project untuk Pengujian AndroidX.
Membuat fragmen
FragmentScenario
menyertakan metode berikut untuk meluncurkan fragmen dalam pengujian:
launchInContainer()
, untuk menguji antarmuka pengguna fragmen.FragmentScenario
akan melampirkan fragmen ke pengontrol tampilan root aktivitas. Aktivitas penampung ini bernilai kosong.launch()
, untuk menguji tanpa antarmuka pengguna fragmen.FragmentScenario
menyertakan jenis fragmen ini ke aktivitas yang kosong dan tidak memiliki tampilan root.
Setelah meluncurkan salah satu jenis fragmen ini, FragmentScenario
akan mengalihkan
status fragmen yang sedang diuji. Secara default, status ini adalah RESUMED
,
tetapi Anda dapat menggantinya dengan argumen initialState
. Status RESUMED
menunjukkan bahwa
fragmen sedang berjalan dan terlihat oleh pengguna. Anda dapat mengevaluasi informasi
tentang elemen UI-nya menggunakan pengujian
UI Espresso.
Contoh kode berikut menunjukkan cara meluncurkan fragmen menggunakan masing-masing metode:
Contoh launchInContainer()
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
// The "fragmentArgs" argument is optional.
val fragmentArgs = bundleOf(“selectedListItem” to 0)
val scenario = launchFragmentInContainer<EventFragment>(fragmentArgs)
...
}
}
Contoh launch()
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
// The "fragmentArgs" arguments are optional.
val fragmentArgs = bundleOf("numElements" to 0)
val scenario = launchFragment<EventFragment>(fragmentArgs)
...
}
}
Menyediakan dependensi
Jika fragmen memiliki dependensi, Anda dapat menyediakan versi uji dependensi tersebut dengan memberikan FragmentFactory
kustom ke metode launchInContainer()
atau launch()
.
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val someDependency = TestDependency()
launchFragmentInContainer {
EventFragment(someDependency)
}
...
}
}
Untuk informasi selengkapnya tentang penggunaan FragmentFactory
dalam memberikan dependensi ke fragmen, lihat
Pengelola fragmen.
Mengalihkan fragmen ke status baru
Dalam pengujian UI aplikasi, biasanya Anda cukup meluncurkan fragmen
yang sedang diuji lalu mulai mengujinya dari status RESUMED
. Namun, dalam pengujian unit yang lebih terperinci, Anda mungkin juga perlu mengevaluasi perilaku fragmen saat bertransisi dari satu status siklus proses ke status siklus proses lainnya. Anda dapat menentukan
status awal dengan meneruskan argumen initialState
ke fungsi
launchFragment*()
mana pun.
Untuk mengalihkan fragmen ke status siklus proses yang berbeda, panggil
moveToState()
.
Metode ini mendukung status berikut sebagai argumen: CREATED
, STARTED
, RESUMED
, dan DESTROYED
. Metode ini menyimulasikan situasi
ketika fragmen atau aktivitas yang berisi fragmen Anda mengubah
statusnya karena alasan apa pun.
Contoh berikut meluncurkan fragmen pengujian dalam status INITIALIZED
, lalu
memindahkannya ke status RESUMED
:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>(
initialState = Lifecycle.State.INITIALIZED
)
// EventFragment has gone through onAttach(), but not onCreate().
// Verify the initial state.
scenario.moveToState(Lifecycle.State.RESUMED)
// EventFragment moves to CREATED -> STARTED -> RESUMED.
...
}
}
Membuat ulang fragmen
Jika aplikasi Anda berjalan di perangkat yang kekurangan resource, sistem
mungkin akan menghapus aktivitas yang berisi fragmen Anda. Situasi ini
mengharuskan aplikasi untuk membuat ulang fragmen saat pengguna kembali ke aplikasi Anda.
Untuk menyimulasikan situasi ini, panggil recreate()
:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>()
scenario.recreate()
...
}
}
FragmentScenario.recreate()
menghapus fragmen dan host-nya, lalu membuatnya kembali. Jika class
FragmentScenario
membuat ulang fragmen yang sedang diuji, fragmen tersebut
akan kembali ke status siklus proses yang telah ada sebelum dihapus.
Berinteraksi dengan fragmen UI
Untuk memicu tindakan UI dalam fragmen yang sedang diuji, gunakan matcher tampilan Espresso untuk berinteraksi dengan elemen dalam tampilan Anda:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>()
onView(withId(R.id.refresh)).perform(click())
// Assert some expected behavior
...
}
}
Jika Anda perlu memanggil metode pada fragmen itu sendiri, seperti merespons
pilihan di menu opsi, Anda dapat aman melakukannya dengan mengambil
referensi ke fragmen menggunakan
FragmentScenario.onFragment()
dan diteruskan dalam
FragmentAction
:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>()
scenario.onFragment { fragment ->
fragment.myInstanceMethod()
}
}
}
Menguji tindakan dialog
FragmentScenario
juga mendukung pengujian
fragmen dialog. Meskipun fragmen dialog
memiliki elemen UI, tata letaknya diisi dalam jendela terpisah, bukan
di aktivitas itu sendiri. Karena alasan ini, gunakan
FragmentScenario.launch()
untuk menguji fragmen dialog.
Contoh berikut akan menguji proses penutupan dialog:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testDismissDialogFragment() {
// Assumes that "MyDialogFragment" extends the DialogFragment class.
with(launchFragment<MyDialogFragment>()) {
onFragment { fragment ->
assertThat(fragment.dialog).isNotNull()
assertThat(fragment.requireDialog().isShowing).isTrue()
fragment.dismiss()
fragment.parentFragmentManager.executePendingTransactions()
assertThat(fragment.dialog).isNull()
}
}
// Assumes that the dialog had a button
// containing the text "Cancel".
onView(withText("Cancel")).check(doesNotExist())
}
}