1. Sebelum memulai
Di codelab sebelumnya, Anda telah mempelajari cara menggunakan ViewModel
untuk menangani logika bisnis, serta LiveData
untuk UI reaktif. Dalam codelab ini, Anda akan mempelajari cara menulis pengujian unit untuk memastikan kode ViewModel
berfungsi dengan benar.
Prasyarat
- Anda telah membuat direktori pengujian di Android Studio.
- Anda telah menulis pengujian unit dan instrumentasi di Android Studio.
- Anda telah menambahkan dependensi Gradle ke project Android.
Yang akan Anda pelajari
- Cara menulis pengujian unit untuk
ViewModel
danLiveData
.
Yang Anda butuhkan
- Komputer yang dilengkapi Android Studio.
- Kode solusi untuk aplikasi Cupcake.
Mendownload kode awal untuk codelab ini
Dalam codelab ini, Anda akan menambahkan uji instrumentasi ke aplikasi Cupcake dari kode solusi sebelumnya.
Untuk mendapatkan kode codelab ini dan membukanya di Android Studio, lakukan hal berikut.
Mendapatkan kode
- Klik URL yang diberikan. Tindakan ini akan membuka halaman GitHub project di browser.
- Periksa dan konfirmasi nama cabang yang cocok dengan nama cabang yang ditentukan dalam codelab. Misalnya, dalam screenshot berikut, nama cabang adalah main (utama).
- Di halaman GitHub project, klik tombol Code yang akan menampilkan pop-up.
- Pada pop-up, klik tombol Download ZIP untuk menyimpan project di komputer. Tunggu download selesai.
- Temukan file di komputer Anda (mungkin di folder Downloads).
- Klik dua kali pada file ZIP untuk mengekstraknya. Tindakan ini akan membuat folder baru yang berisi file project.
Membuka project di Android Studio
- Mulai Android Studio.
- Di jendela Welcome to Android Studio, klik Open.
Catatan: Jika Android Studio sudah terbuka, pilih opsi menu File > Open.
- Di file browser, buka lokasi folder project yang telah diekstrak (kemungkinan ada di folder Downloads).
- Klik dua kali pada folder project tersebut.
- Tunggu Android Studio membuka project.
- Klik tombol Run untuk membangun dan menjalankan aplikasi. Pastikan aplikasi dibangun seperti yang diharapkan.
2. Ringkasan aplikasi awal
Aplikasi Cupcake terdiri dari layar utama yang menampilkan layar pesanan dengan tiga opsi jumlah cupcake. Dengan mengklik opsi, Anda akan berpindah ke layar pemilihan rasa, lalu Anda diarahkan ke layar pemilihan tanggal pengambilan pesanan. Setelah itu, Anda dapat mengirimkan pesanan ke aplikasi lain. Anda dapat membatalkan pesanan di salah satu tahap ini.
3. Membuat direktori pengujian unit
Buat direktori pengujian unit untuk aplikasi Cupcake seperti yang telah Anda lakukan di codelab sebelumnya.
4. Membuat class pengujian unit
Buat class baru bernama ViewModelTests.kt.
5. Menambahkan dependensi yang diperlukan
Tambahkan dependensi berikut ke project Anda:
testImplementation 'junit:junit:4.+'
testImplementation 'androidx.arch.core:core-testing:2.1.0'
Sekarang sinkronkan project Anda.
6. Menulis pengujian ViewModel
Mari kita mulai dengan pengujian sederhana. Hal pertama yang kita lakukan saat berinteraksi dengan aplikasi di perangkat atau emulator adalah memilih jumlah cupcake. Jadi pertama-tama kita akan menguji metode setQuantity()
di OrderViewModel
, dan memeriksa nilai objek quantity
LiveData
.
Variabel quantity
, yang akan kita uji, adalah instance LiveData
. Pengujian objek LiveData
memerlukan langkah tambahan, dan di sinilah dependensi yang telah kita tambahkan akan berperan. Kita menggunakan LiveData
untuk memperbarui UI segera setelah nilai berubah. UI kita berjalan pada "thread utama". Bukan masalah jika Anda tidak terbiasa dengan pembuatan thread dan konkurensi karena kami akan membahasnya secara mendalam di codelab lainnya. Untuk saat ini, dalam konteks aplikasi Android, anggap thread utama sebagai thread UI. Kode yang menampilkan UI kepada pengguna yang berjalan di thread ini. Kecuali jika ditentukan lain, pengujian unit mengasumsikan bahwa semua UI berjalan di thread utama. Namun, karena objek LiveData
tidak dapat mengakses thread utama, kita harus menyatakan secara eksplisit bahwa objek LiveData
tidak boleh memanggil thread utama.
- Untuk menentukan bahwa objek
LiveData
tidak boleh memanggil thread utama, kita perlu menyediakan aturan pengujian tertentu setiap kali menguji objekLiveData
.
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
- Sekarang kita dapat membuat fungsi bernama
quantity_twelve_cupcakes()
. Dalam metode ini, buat instanceOrderViewModel.
- Dalam pengujian ini, Anda akan memeriksa untuk memastikan objek
quantity
diOrderViewModel
diperbarui saatsetQuantity
dipanggil. Namun, sebelum memanggil metode apa pun atau menggunakan data diOrderViewModel
, penting untuk diperhatikan bahwa saat menguji nilai objekLiveData
, objek harus diamati agar perubahan dapat ditampilkan. Cara mudah untuk melakukannya adalah dengan menggunakan metodeobserveForever
. Panggil metodeobserveForever
pada objekquantity
. Metode ini memerlukan ekspresi lambda, tetapi boleh kosong. - Lalu, panggil metode
setQuantity()
dengan meneruskan12
sebagai parameter.
val viewModel = OrderViewModel()
viewModel.quantity.observeForever {}
viewModel.setQuantity(12)
- Kita dapat dengan aman menyimpulkan bahwa nilai objek
quantity
adalah12
. Perlu diketahui bahwa objekLiveData
bukanlah nilai itu sendiri. Nilai dimuat dalam properti yang disebutvalue
. Buat pernyataan berikut:
assertEquals(12, viewModel.quantity.value)
Pengujian Anda akan terlihat seperti ini:
@Test
fun quantity_twelve_cupcakes() {
val viewModel = OrderViewModel()
viewModel.quantity.observeForever {}
viewModel.setQuantity(12)
assertEquals(12, viewModel.quantity.value)
}
Jalankan pengujian. Selamat, Anda baru saja menulis pengujian unit LiveData
pertama yang merupakan keterampilan penting dalam pengembangan Android modern. Pengujian ini tidak menguji banyak logika bisnis. Jadi, mari menulis pengujian yang sedikit lebih menggunakan logika bisnis.
Salah satu fungsi utama OrderViewModel
adalah menghitung harga pesanan. Hal ini terjadi saat kita memilih jumlah cupcake, dan memilih tanggal pengambilan. Penghitungan harga dilakukan dengan metode pribadi sehingga pengujian tidak dapat memanggil metode ini secara langsung. Hanya metode lain di OrderViewModel
yang dapat memanggilnya. Metode ini bersifat publik. Jadi, kita akan memanggilnya agar memicu penghitungan harga sehingga kita dapat memeriksa apakah nilai harganya sesuai dengan harapan atau tidak.
Praktik terbaik
Harga diperbarui saat jumlah cupcake dan juga tanggal dipilih. Meskipun keduanya harus diuji, umumnya lebih baik hanya menguji satu fungsi. Oleh karena itu, kita akan membuat metode terpisah untuk setiap pengujian: satu fungsi guna menguji harga saat jumlah diperbarui, dan fungsi terpisah untuk menguji harga saat tanggal diperbarui. Kami tidak ingin hasil pengujian gagal dengan alasan pengujian yang berbeda gagal.
- Buat metode yang disebut
price_twelve_cupcakes()
dan anotasikan sebagai pengujian. - Dalam metode ini, buat instance
OrderViewModel
dan panggil metodesetQuantity()
dengan meneruskan 12 sebagai parameter.
val viewModel = OrderViewModel()
viewModel.setQuantity(12)
- Dengan melihat
PRICE_PER_CUPCAKE
diOrderViewModel
, kita jadi tahu harga setiap cupcake adalah $2,00. Kita juga dapat melihat bahwaresetOrder()
dipanggil setiap kaliViewModel
diinisialisasi, dan dalam metode ini, tanggal default adalah tanggal hari ini, danPRICE_FOR_SAME_DAY_PICKUP
adalah $3,00. Jadi, 12 * 2 + 3 = 27. Setelah memilih 12 cupcake, kita memperkirakan nilai variabelprice
menjadi $27,00. Jadi, mari buat pernyataan bahwa nilai yang diharapkan sebesar $27,00 sama dengan nilai objekprice LiveData
.
assertEquals("$27.00", viewModel.price.value)
Sekarang jalankan pengujian.
Gagal!
Hasil pengujian menyatakan bahwa nilai sebenarnya adalah null
. Ada penjelasan untuk hal ini. Jika melihat variabel price
di OrderViewModel
, Anda akan melihat ini:
val price: LiveData<String> = Transformations.map(_price) {
// Format the price into the local currency and return this as LiveData<String>
NumberFormat.getCurrencyInstance().format(it)
}
Ini adalah contoh alasan LiveData
harus diamati dalam pengujian. Nilai price
disetel dengan menggunakan Transformation
. Pada dasarnya, kode ini menggunakan nilai yang telah kita setel ke price
dan mengubahnya ke format mata uang sehingga kita tidak perlu melakukannya secara manual. Namun, kode ini memiliki implikasi lainnya. Saat mengubah objek LiveData
, kode tidak akan dipanggil kecuali jika diperlukan. Hal ini akan menghemat resource di perangkat seluler. Kode hanya akan dipanggil jika kita mengamati objek untuk perubahan. Tentu saja hal ini dilakukan di aplikasi kita, tetapi kita juga perlu melakukan hal yang sama untuk pengujian.
- Dalam metode pengujian, tambahkan baris berikut sebelum menetapkan jumlah:
viewModel.price.observeForever {}
Pengujian Anda akan terlihat seperti ini:
@Test
fun price_twelve_cupcakes() {
val viewModel = OrderViewModel()
viewModel.price.observeForever {}
viewModel.setQuantity(12)
assertEquals("$27.00", viewModel.price.value)
}
Sekarang, pengujian yang akan Anda jalankan seharusnya lulus.
7. Kode solusi
8. Selamat
Dalam codelab ini, kita telah:
- Mempelajari cara menyiapkan pengujian
LiveData
. - Mempelajari cara menguji
LiveData
itu sendiri. - Mempelajari cara menguji
LiveData
yang ditransformasi. - Mempelajari cara mengamati
LiveData
dalam pengujian unit.