Pengujian Unit dengan JUnit
Tulis pengujian unit yang cepat dan andal dengan JUnit 4. Gunakan @Test, @Before, @After, assertion, uji LiveData dengan InstantTaskExecutorRule, dan uji coroutine dengan runTest.
Pengujian Unit dengan JUnit adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Android Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Android Academy mencakup 4 pelajaran total.
Mengapa Menulis Pengujian?
Pengujian bukan kemewahan — pengujian adalah jaring pengaman Anda:
- Menemukan bug sebelum pengguna menemukannya
- Melakukan refaktor dengan percaya diri (jika pengujian berhasil, tidak ada yang rusak)
- Mendokumentasikan perilaku yang diharapkan
- Mencegah regresi saat menambahkan fitur
Kode yang diuji dengan baik juga cenderung memiliki rancangan yang lebih baik — jika sulit diuji, kemungkinan besar rancangannya terlalu erat keterkaitannya.
Jenis Pengujian Android
Dua kategori:
- Pengujian unit (folder
test/) — dijalankan pada JVM, tidak memerlukan perangkat. Cepat. Menguji logika Kotlin/Java biasa. - Pengujian berinstrumentasi (folder
androidTest/) — dijalankan pada perangkat atau emulator. Lebih lambat. Menguji kode khusus Android (basis data Room, UI).
Utamakan pengujian unit untuk logika bisnis. Gunakan pengujian berinstrumentasi hanya jika Anda harus berinteraksi dengan API Android.
Penyiapan JUnit 4
JUnit 4 disertakan secara default dalam proyek Android. Tambahkan ini ke app/build.gradle:
// app/build.gradle:
dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
testImplementation 'androidx.arch.core:core-testing:2.2.0' // for LiveData
}Pengujian JUnit Pertama Anda
Buat kelas dalam src/test/java/ dan beri anotasi @Test pada metode pengujian:
import org.junit.Test
import org.junit.Assert.*
class CalculatorTest {
private val calc = Calculator()
@Test
fun `addition returns correct sum`() {
val result = calc.add(2, 3)
assertEquals(5, result)
}
@Test
fun `division by zero throws exception`() {
assertThrows(ArithmeticException::class.java) {
calc.divide(10, 0)
}
}
}@Before dan @After
Gunakan anotasi siklus hidup untuk menyiapkan dan membongkar keadaan di sekitar setiap pengujian:
class UserRepositoryTest {
private lateinit var repo: UserRepository
private lateinit var fakeDao: FakeUserDao
@Before
fun setUp() {
fakeDao = FakeUserDao() // fresh instance before each test
repo = UserRepository(fakeDao)
}
@After
fun tearDown() {
fakeDao.clear() // clean up after each test
}
@Test
fun `getUsers returns all users`() {
fakeDao.insert(User(1, "Alice"))
fakeDao.insert(User(2, "Bob"))
assertEquals(2, repo.getUsers().size)
}
}Pernyataan Umum
JUnit menyediakan metode pernyataan dalam Assert.*:
// Equality:
assertEquals(expected, actual)
assertNotEquals(unexpected, actual)
// Null:
assertNull(value)
assertNotNull(value)
// Boolean:
assertTrue(condition)
assertFalse(condition)
// Same object reference:
assertSame(expected, actual)
// Custom message on failure:
assertEquals("User ID should be 1", 1, user.id)
// Exception:
assertThrows(IllegalArgumentException::class.java) {
User(id = -1, name = "")
}Menguji ViewModel
Untuk menguji LiveData, tambahkan InstantTaskExecutorRule agar LiveData mengirimkan pembaruan secara sinkron:
class UserViewModelTest {
@get:Rule
val instantTaskRule = InstantTaskExecutorRule()
private val fakeRepo = FakeUserRepository()
private lateinit var viewModel: UserViewModel
@Before
fun setUp() {
viewModel = UserViewModel(fakeRepo)
}
@Test
fun `users are loaded on init`() {
fakeRepo.usersToReturn = listOf(User(1, "Alice"), User(2, "Bob"))
viewModel.loadUsers()
val result = viewModel.users.value
assertNotNull(result)
assertEquals(2, result?.size)
}
}Menguji Coroutine
Gunakan TestCoroutineDispatcher / StandardTestDispatcher untuk mengontrol eksekusi coroutine dalam pengujian:
class SyncWorkerTest {
@get:Rule
val instantTaskRule = InstantTaskExecutorRule()
private val testDispatcher = StandardTestDispatcher()
@Before
fun setUp() {
Dispatchers.setMain(testDispatcher)
}
@After
fun tearDown() {
Dispatchers.resetMain()
}
@Test
fun `sync completes successfully`() = runTest {
val repo = FakeRepository()
val worker = SyncUseCase(repo, testDispatcher)
val result = worker.run()
assertTrue(result.isSuccess)
}
}Fake vs Mock
Dua strategi untuk mengganti dependensi nyata dalam pengujian:
- Fake — implementasi yang berfungsi dan dirancang untuk pengujian (misalnya daftar dalam memori sebagai pengganti basis data nyata). Mudah ditulis, mudah dibaca, dan tidak memerlukan pustaka.
- Mock — stub yang dibuat otomatis, yang mencatat pemanggilan dan memungkinkan Anda memverifikasi interaksi (Mockito, MockK). Lebih canggih, tetapi dapat menjadi rapuh jika digunakan berlebihan.
Utamakan Fake untuk kasus sederhana; gunakan Mock jika Anda perlu memverifikasi pemanggilan metode.
Menulis Fake
Fake menerapkan interface yang sama seperti kelas nyata, tetapi menggunakan penyimpanan dalam memori:
interface UserDao {
fun getAll(): List<User>
fun insert(user: User)
}
class FakeUserDao : UserDao {
private val storage = mutableListOf<User>()
override fun getAll(): List<User> = storage.toList()
override fun insert(user: User) { storage.add(user) }
fun clear() { storage.clear() }
}Konvensi Penamaan Pengujian
Nama pengujian yang baik menjelaskan hal yang diuji dan hasil yang diharapkan. Gunakan nama fungsi dengan tanda backtick dalam Kotlin agar deskripsinya mudah dibaca:
`getUsers returns empty list when no users exist``login throws exception when password is blank``add returns correct sum for negative numbers`
Pola: `subject does X when Y`
Pemeriksaan Cepat
Apa tujuan @Before dalam kelas pengujian JUnit?
Ringkasan: Pengujian Unit dengan JUnit
Aplikasi yang andal adalah aplikasi yang diuji:
- Pengujian unit ditempatkan di
src/test/dan dijalankan pada JVM — cepat - Beri anotasi dengan
@Test, gunakanassertEquals,assertTrue,assertThrows @Before/@Afteruntuk penyiapan dan pembongkaranInstantTaskExecutorRuleuntuk menguji LiveData secara sinkronrunTest+StandardTestDispatcheruntuk pengujian coroutine- Utamakan Fake daripada Mock untuk penggantian sederhana
Berikutnya: Mocking dengan Mockito untuk memverifikasi interaksi.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Pengujian Unit dengan JUnit” gratis?
Ya — teks lengkap “Pengujian Unit dengan JUnit” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Android Academy, upgrade ke CoddyKit PRO. Kursus Android Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Pengujian Unit dengan JUnit”?
Tulis pengujian unit yang cepat dan andal dengan JUnit 4. Gunakan @Test, @Before, @After, assertion, uji LiveData dengan InstantTaskExecutorRule, dan uji coroutine dengan runTest. Kamu berlatih Android Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Android Academy?
Tidak diperlukan pengalaman sebelumnya. Android Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.
Berapa lama pelajaran “Pengujian Unit dengan JUnit” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Android Academy ini?
Ya. Setiap pelajaran Android Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pengujian Unit dengan JUnit
- Mocking dengan Mockito
- Pengujian Antarmuka dengan Espresso
- Debugging & Pembuatan Profil