Logika aplikasi dapat dievaluasi menggunakan pengujian unit lokal saat Anda perlu menjalankan pengujian lebih cepat dan tidak memerlukan fidelitas serta keyakinan yang terkait dengan menjalankan pengujian di perangkat sebenarnya. Dengan pendekatan ini, Anda biasanya dapat memenuhi hubungan dependensi menggunakan Robolectric atau framework tiruan, seperti Mockito. Biasanya, jenis dependensi yang terkait dengan pengujian menentukan alat mana yang Anda gunakan:
- Jika memiliki dependensi pada framework Android, khususnya yang membuat interaksi kompleks dengan framework, sebaiknya Anda menyertakan dependensi framework menggunakan Robolectric.
- Jika pengujian memiliki dependensi minimal pada framework Android, atau jika pengujian hanya bergantung pada objek Anda sendiri, Anda dapat menyertakan dependensi tiruan menggunakan framework tiruan seperti Mockito.
Menyiapkan lingkungan pengujian Anda
Dalam project Android Studio, Anda harus menyimpan file sumber untuk pengujian unit lokal di module-name/src/test/java/
. Direktori ini sudah ada saat Anda membuat project baru.
Anda juga perlu mengonfigurasi dependensi pengujian untuk project Anda agar dapat menggunakan API standar yang diberikan oleh framework JUnit 4. Jika pengujian Anda perlu berinteraksi dengan dependensi Android, sertakan Robolectric atau library Mockito untuk menyederhanakan pengujian unit lokal Anda.
Di file build.gradle
tingkat teratas aplikasi, tentukan library berikut sebagai dependensi:
dependencies { // Required -- JUnit 4 framework testImplementation 'junit:junit:4.12' // Optional -- Robolectric environment testImplementation 'androidx.test:core:1.0.0' // Optional -- Mockito framework testImplementation 'org.mockito:mockito-core:1.10.19' }
Membuat class pengujian unit lokal
Class pengujian unit lokal Anda harus ditulis sebagai class pengujian JUnit 4. JUnit adalah framework pengujian unit yang paling populer dan banyak digunakan untuk Java. JUnit 4 memungkinkan Anda untuk menulis pengujian dengan cara yang lebih rapi dan fleksibel daripada versi pendahulunya karena JUnit 4 tidak mengharuskan Anda untuk melakukan hal-hal berikut:
- Perluas class
junit.framework.TestCase
. - Berikan awalan pada nama metode pengujian Anda dengan kata kunci
'test'
. - Gunakan class dari paket
junit.framework
ataujunit.extensions
.
Untuk membuat class pengujian JUnit 4 dasar, buat class yang berisi satu atau beberapa metode pengujian.
Sebuah metode pengujian dimulai dengan anotasi @Test
dan berisi kode untuk menerapkan serta memverifikasi fungsionalitas tunggal dalam komponen yang ingin Anda uji.
Contoh berikut menunjukkan cara mengimplementasikan class pengujian unit lokal. Metode pengujian emailValidator_CorrectEmailSimple_ReturnsTrue
memverifikasi bahwa metode isValidEmail()
di aplikasi yang diuji menampilkan hasil yang benar.
Kotlin
import com.google.common.truth.Truth.assertThat import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertThat(EmailValidator.isValidEmail("name@email.com")).isTrue() } }
Java
import com.google.common.truth.Truth.assertThat; import org.junit.Test; public class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertThat(EmailValidator.isValidEmail("name@email.com")).isTrue(); } }
Untuk membuat pengujian dapat dibaca yang mengevaluasi apakah komponen-komponen dalam aplikasi Anda menunjukkan hasil yang diharapkan, sebaiknya gunakan library Truth dan class dari Android Assertion, seperti yang ditunjukkan di contoh sebelumnya. Untuk mempelajari lebih lanjut jenis validasi logika yang didukung oleh Truth dan Android Assertion, lihat bagian yang menjelaskan cara membuat pernyataan yang lebih mudah dibaca.
Jika Anda lebih senang membandingkan antara hasil yang diharapkan dengan hasil sebenarnya menggunakan metode junit.Assert atau Hamcrest matchers (seperti metode is()
dan equalTo()
), Anda dapat menggunakan library tersebut sebagai gantinya.
Catatan: Hamcrest adalah library pilihan untuk digunakan saat membuat matcher, seperti untuk class ViewMatcher
Espresso.
Menyertakan dependensi framework
Jika pengujian Anda berinteraksi dengan beberapa dependensi framework Android, atau berinteraksi dengan dependensi tersebut secara kompleks, gunakan artefak Robolectric yang diberikan oleh Pengujian AndroidX. Robolectric menjalankan kode framework Android asli dan kode framework native palsu di JVM lokal atau di perangkat sebenarnya.
Contoh berikut menunjukkan cara membuat pengujian unit yang menggunakan Robolectric:
app/build.gradle
android { // ... testOptions { unitTests.includeAndroidResources = true } }
MyLocalUnitTestClass
Kotlin
import android.content.Context import androidx.test.core.app.ApplicationProvider import com.google.common.truth.Truth.assertThat import org.junit.Test private const val FAKE_STRING = "HELLO_WORLD" class UnitTestSample { val context = ApplicationProvider.getApplicationContext<Context>() @Test fun readStringFromContext_LocalizedString() { // Given a Context object retrieved from Robolectric... val myObjectUnderTest = ClassUnderTest(context) // ...when the string is returned from the object under test... val result: String = myObjectUnderTest.getHelloWorldString() // ...then the result should be the expected one. assertThat(result).isEqualTo(FAKE_STRING) } }
Java
import android.content.Context; import androidx.test.core.app.ApplicationProvider; import org.junit.Test; import static com.google.common.truth.Truth.assertThat; public class UnitTestSampleJava { private static final String FAKE_STRING = "HELLO_WORLD"; private Context context = ApplicationProvider.getApplicationContext(); @Test public void readStringFromContext_LocalizedString() { // Given a Context object retrieved from Robolectric... ClassUnderTest myObjectUnderTest = new ClassUnderTest(context); // ...when the string is returned from the object under test... String result = myObjectUnderTest.getHelloWorldString(); // ...then the result should be the expected one. assertThat(result).isEqualTo(FAKE_STRING); } }
Menyertakan class Android Builder
Jika membuat pengujian unit lokal yang dijalankan di lingkungan Robolectric atau di perangkat sebenarnya, Anda dapat menggunakan builder yang disediakan Pengujian AndroidX untuk beberapa class framework umum. Builder tersebut memungkinkan Anda untuk membuat instance dari class berikut tanpa perlu menggunakan tiruan atau refleksi:
Menggunakan class utilitas Parcelables
Selain itu, library juga memberikan class utilitas untuk objek Parcelable
. Dengan memberikan objek Creator
, class ini melakukan unmarshal kepada objek Parcelable
yang diberikan, lalu melakukan marshal kepada objek Parcelable
duplikat.
Catatan: Metode yang memanggil Parcelables.forceParcel()
akan menjadi penentu apakah operasi unmarshal/remarshal telah berhasil atau tidak.
Menyertakan dependensi tiruan
Secara default, Plugin Android untuk Gradle menjalankan pengujian unit lokal Anda terhadap versi modifikasi library android.jar
, yang tidak berisi kode aktual. Sebagai gantinya, metode yang memanggil ke class Android dari pengujian unit Anda akan memunculkan pengecualian. Perilaku ini memastikan Anda hanya menguji kode Anda dan tidak bergantung pada perilaku tertentu dari platform Android (yang belum dibuat atau ditiru secara eksplisit).
Meniru dependensi Android
Jika Anda memiliki dependensi Android minimal serta perlu menguji interaksi spesifik antara komponen dan dependensinya dalam aplikasi, gunakan framework tiruan untuk menghentikan dependensi eksternal dalam kode Anda. Dengan begitu, Anda dapat dengan mudah menguji apakah komponen berinteraksi dengan dependensi menggunakan cara yang diharapkan. Dengan mengganti dependensi Android dengan objek tiruan, Anda dapat memisahkan pengujian unit dari sistem Android lainnya sambil memverifikasi bahwa metode yang benar dalam dependensi tersebut dipanggil. Framework tiruan Mockito untuk Java (versi 1.9.5 dan yang lebih tinggi) menawarkan kompatibilitas dengan pengujian unit Android. Dengan Mockito, Anda dapat mengonfigurasi objek tiruan untuk menampilkan nilai tertentu saat dipanggil.
Untuk menambahkan objek tiruan ke pengujian unit lokal Anda menggunakan framework ini, ikuti model pemrograman berikut:
- Sertakan dependensi library Mockito dalam file
build.gradle
, seperti yang dijelaskan dalam Menyiapkan lingkungan pengujian Anda. - Di awal definisi class pengujian unit, tambahkan anotasi
@RunWith(MockitoJUnitRunner.class)
. Anotasi ini memberi tahu runner pengujian Mockito untuk memvalidasi bahwa penggunaan framework sudah benar dan menyederhanakan inisialisasi objek tiruan Anda. - Untuk membuat objek tiruan untuk dependensi Android, tambahkan anotasi
@Mock
sebelum deklarasi kolom. - Untuk menghentikan perilaku dependensi, Anda dapat menentukan kondisi dan mengembalikan nilai saat kondisi terpenuhi dengan menggunakan metode
when()
danthenReturn()
.
Contoh berikut menunjukkan cara membuat pengujian unit yang menggunakan objek Context
tiruan.
Kotlin
import android.content.Context import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnitRunner private const val FAKE_STRING = "HELLO WORLD" @RunWith(MockitoJUnitRunner::class) class UnitTestSample { @Mock private lateinit var mockContext: Context @Test fun readStringFromContext_LocalizedString() { // Given a mocked Context injected into the object under test... `when`(mockContext.getString(R.string.hello_word)) .thenReturn(FAKE_STRING) val myObjectUnderTest = ClassUnderTest(mockContext) // ...when the string is returned from the object under test... val result: String = myObjectUnderTest.getHelloWorldString() // ...then the result should be the expected one. assertThat(result, `is`(FAKE_STRING)) } }
Java
import android.content.Context; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class UnitTestSample { private static final String FAKE_STRING = "HELLO WORLD"; @Mock Context mockContext; @Test public void readStringFromContext_LocalizedString() { // Given a mocked Context injected into the object under test... when(mockContext.getString(R.string.hello_world)) .thenReturn(FAKE_STRING); ClassUnderTest myObjectUnderTest = new ClassUnderTest(mockContext); // ...when the string is returned from the object under test... String result = myObjectUnderTest.getHelloWorldString(); // ...then the result should be the expected one. assertThat(result, is(FAKE_STRING)); } }
Untuk mempelajari lebih lanjut cara menggunakan framework Mockito, lihat referensi Mockito API dan class SharedPreferencesHelperTest
dalam kode contoh. Coba juga Android Testing Codelab.
Error: "Metode ... tidak ditiru"
Jika Anda menjalankan pengujian yang memanggil API dari Android SDK yang tidak Anda tiru, error yang memberitahukan metode ini tidak ditiru akan muncul. Ini terjadi karena file android.jar
yang digunakan untuk menjalankan pengujian unit tidak berisi kode aktual (API tersebut hanya diberikan oleh image sistem Android pada perangkat).
Sebagai gantinya, semua metode akan memunculkan pengecualian secara default. Perilaku ini memastikan pengujian unit hanya menguji kode Anda dan tidak bergantung pada perilaku tertentu dari platform Android (yang belum Anda tiru secara eksplisit, seperti dengan Mockito).
Jika pengecualian yang dimunculkan bermasalah bagi pengujian, Anda dapat mengubah perilaku tersebut sehingga metode akan menampilkan null atau nol dengan menambahkan konfigurasi berikut dalam file build.gradle
tingkat teratas project Anda:
android { ... testOptions { unitTests.returnDefaultValues = true } }
Perhatian: Menyetel properti returnDefaultValues
ke true
harus dilakukan dengan hati-hati. Nilai-nilai pengembalian null/nol dapat menyebabkan regresi dalam pengujian Anda, yang sulit untuk di-debug dan mungkin meluluskan pengujian yang gagal. Hanya gunakan langkah tersebut sebagai pilihan terakhir.
Menjalankan pengujian unit lokal
Untuk menjalankan pengujian unit lokal, gunakan langkah-langkah berikut:
- Pastikan project Anda disinkronkan dengan Gradle dengan mengklik Sync Project
di toolbar.
- Jalankan pengujian Anda dengan salah satu cara berikut:
- Untuk menjalankan pengujian tunggal, buka jendela Project, lalu klik kanan pengujian dan klik Run
.
- Untuk menguji semua metode di suatu class, klik kanan class atau metode di file pengujian dan klik Run
.
- Untuk menjalankan semua pengujian di suatu direktori, klik kanan pada direktori dan pilih Run tests
.
- Untuk menjalankan pengujian tunggal, buka jendela Project, lalu klik kanan pengujian dan klik Run
Plugin Android untuk Gradle mengompilasi kode pengujian unit lokal yang terletak di direktori default (src/test/java/
), membuat aplikasi pengujian, dan menjalankannya secara lokal menggunakan class runner pengujian default. Android Studio kemudian menampilkan hasilnya di jendela Run.