TDD: apa itu, prinsip pengujian dan metodologi

Penulis: IT Sectr Diterbitkan: 2026-04-09 Waktu membaca: 9 mnt

Test-Driven Development (TDD) — adalah metodologi pengembangan di mana tes ditulis sebelum implementasi kode. Pengembang pertama-tama merumuskan perilaku yang diharapkan dalam bentuk tes yang gagal, kemudian menulis kode minimal untuk meloloskan tes tersebut, dan setelah itu merefaktor hasilnya. Menurut Martin Fowler (2023), TDD bukanlah teknik pengujian — ini adalah teknik desain yang mendisiplinkan arsitektur dan mengurangi jumlah cacat pada tahap penulisan kode.

Poin Utama

  • TDD — metodologi di mana tes ditulis sebelum implementasi, bukan setelahnya
  • Siklus Red-Green-Refactor — dasar TDD: tes merah, tes hijau, refactoring
  • JUnit dan Mockito — alat utama untuk TDD dalam pengembangan Android
  • Cakupan kode dalam proyek TDD sering melebihi 90% berkat disiplin “tes di atas segalanya”
  • Refactoring tanpa takut merusak fungsionalitas — keuntungan utama pendekatan TDD

Apa itu TDD?

Test-Driven Development — adalah praktik pengembangan perangkat lunak di mana tes otomatis menentukan penulisan kode produksi. Berbeda dengan pendekatan tradisional di mana kode ditulis lalu diuji, TDD membalik urutannya: pertama tes ditulis, kemudian kode yang meloloskan tes tersebut.

Pendiri TDD dianggap Kent Beck, yang merumuskan praktik ini pada akhir tahun 1990-an dalam kerangka metodologi Extreme Programming (XP). Dalam buku “Test-Driven Development: By Example” (2002) Beck menjelaskan lima aturan TDD yang menjadi kanonik: tulis tes sebelum kode produksi, tulis kode sebanyak yang diperlukan untuk meloloskan tes, dan refaktor setelah setiap siklus.

Prinsip utama TDD

Prinsip pertama — tes menentukan antarmuka. Pengembang dipaksa untuk memikirkan bagaimana komponen akan digunakan sebelum memikirkan bagaimana komponen tersebut diimplementasikan. Ini membentuk API yang bersih sejak awal.

TDD sebagai teknik desain

Prinsip kedua — implementasi minimal. Ketika tes sudah ditulis, pengembang menulis kode produksi sebanyak yang diperlukan untuk meloloskan tes — tidak lebih. Ini mencegah abstraksi prematur dan kompleksitas berlebihan yang oleh Martin Fowler disebut Speculative Generality.

Perbedaan TDD dengan pengujian biasa

Perbedaan utama antara TDD dan pengujian “setelah fakta” — disiplin urutan. Dalam TDD, tes tidak hanya memeriksa kode — tetapi mengarahkan strukturnya. Menurut penelitian Microsoft Research (Nagappan et al., 2008), tim yang menerapkan TDD menunjukkan pengurangan kepadatan cacat sebesar 40–90% dibandingkan dengan tim yang menggunakan pendekatan tradisional.

Siklus Red-Green-Refactor

Siklus Red-Green-Refactor — adalah urutan tiga langkah yang diulang untuk setiap tes baru. Red: tulis tes yang gagal. Green: tulis kode minimal agar tes lolos. Refactor: tingkatkan kode tanpa mengubah perilakunya.

Fase Red: menulis tes yang gagal

Pengembang menulis tes yang memeriksa fungsionalitas yang belum diimplementasikan. Pada tahap ini tes harus gagal — ini mengonfirmasi bahwa tes benar-benar memeriksa sesuatu. Di lingkungan pengembangan Android, framework JUnit 5 menunjukkan indikasi merah untuk tes yang gagal, yang memberi nama pada fase ini.

kotlin
class CalculatorTest {
    fun testAddition() {
        val result = Calculator().add(2, 3)
        Assertions.assertEquals(5, result)
    }
}

Fase Green: implementasi minimal

Pada tahap ini, kode produksi minimal ditulis yang cukup untuk meloloskan tes. Tidak ada redundansi — hanya apa yang diperlukan untuk indikasi hijau. Jika implementasi bisa berupa konstanta — biarkan konstanta. Refactoring akan terjadi pada langkah berikutnya ketika tes baru muncul.

kotlin
class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }
}

Fase Refactor: peningkatan tanpa risiko

Tes hijau adalah asuransi untuk refactoring. Pengembang dapat menulis ulang implementasi, mengoptimalkan kinerja, atau meningkatkan keterbacaan, dengan keyakinan bahwa tes akan segera mendeteksi setiap penyimpangan dari perilaku yang diharapkan. Dalam pengembangan mobile di Android, fase ini sangat penting untuk memisahkan antarmuka umum dan mengurangi duplikasi kode.

Keuntungan TDD dalam pengembangan mobile

Penerapan TDD dalam proyek mobile memberikan keuntungan yang terukur, dikonfirmasi oleh penelitian akademis maupun praktik studio pengembangan terkemuka.

Pengurangan kepadatan cacat

Penelitian IBM (Bhat & Nagappan, 2006) pada empat proyek industri menunjukkan bahwa tim yang menggunakan TDD membuat 40% lebih sedikit cacat dibandingkan dengan tim serupa yang bekerja secara tradisional. Untuk pengembangan mobile, di mana biaya perbaikan bug setelah rilis di Google Play jauh lebih tinggi daripada pada tahap penulisan kode, metrik ini sangat penting.

Dokumentasi kode melalui tes

Tes yang ditulis sesuai TDD berfungsi sebagai dokumentasi hidup API. Pengembang yang datang ke proyek dapat membaca tes dan memahami bagaimana setiap komponen harus digunakan. Ini sangat berharga dalam kondisi pergantian tim yang tinggi — masalah umum studio mobile.

Refactoring yang percaya diri

Cakupan kode oleh tes yang melebihi 90% memungkinkan pengembang melakukan refactoring tanpa takut merusak sesuatu. Google dalam bukunya “Software Engineering at Google” (2020) menyebut cakupan tes sebagai faktor kunci yang memungkinkan menjaga basis kode tetap bersih dalam proyek dengan jutaan baris kode.

Alat dan framework untuk TDD

Ekosistem TDD dalam pengembangan mobile mencakup alat untuk pengujian unit, mocking, dan pemeriksaan komponen UI — baik untuk Android maupun iOS.

AlatPlatformTujuan
JUnit 5Android (Kotlin/Java)Framework dasar untuk pengujian unit
MockitoAndroidPembuatan objek mock dan verifikasi panggilan
MockKAndroid (Kotlin)Mocking dengan sintaks Kotlin-first dan dukungan coroutine
TurbineAndroidPengujian Kotlin Flow dan aliran reaktif
XCTestiOS (Swift)Framework pengujian standar

Memilih framework untuk Android

Untuk proyek Android di Kotlin, tumpukan standar mencakup JUnit 5 + MockK. MockK lebih disukai daripada Mockito karena mendukung fungsi kelas satu Kotlin — sealed class, coroutine, dan suspend-fungsi tanpa konfigurasi tambahan.

Alat untuk iOS

Dalam pengembangan iOS, TDD diimplementasikan melalui XCTest — framework bawaan Apple yang menyediakan asersi, kelas tes, dan integrasi dengan CI/CD melalui Xcode Server atau GitHub Actions. Untuk mocking di iOS, digunakan pustaka Cuckoo dan OHHTTPStubs.

Contoh kode TDD di Kotlin

Mari kita lihat skenario TDD nyata di Kotlin untuk Android — pengujian repositori pengguna. Pertama kita menulis tes, kemudian — implementasi yang meloloskan tes tersebut.

Langkah 1: tes untuk UserRepository

kotlin
class UserRepositoryTest {
    private val api = mockk<UserApi>()
    private val dao = mockk<UserDao>()
    private val repo = UserRepository(api, dao)

    fun `when api returns user then cache and emit`() = runTest {
        val user = User(1, "Alice")
        coEvery { api.getUser(1) } returns user
        every { dao.insert(user) } returns Unit

        val result = repo.getUser(1)

        assertEquals(user, result)
        verify { dao.insert(user) }
    }
}

Langkah 2: implementasi minimal

kotlin
class UserRepository(
    private val api: UserApi,
    private val dao: UserDao
) {
    suspend fun getUser(id: Int): User {
        val user = api.getUser(id)
        dao.insert(user)
        return user
    }
}

Langkah 3: tes untuk caching dengan mode offline

Setelah meloloskan tes pertama, kita menambahkan tes kedua — memeriksa perilaku saat kesalahan jaringan. Sekarang tes menentukan bahwa ketika API gagal, repositori harus mengembalikan data dari cache.

kotlin
fun `when api fails then return cached user`() = runTest {
    val cached = User(1, "Cached Alice")
    coEvery { api.getUser(1) } throws IOException()
    every { dao.getById(1) } returns cached

    val result = repo.getUser(1)

    assertEquals(cached, result)
}

Kesalahan umum dalam penerapan TDD

Transisi ke TDD disertai dengan kesalahan umum yang dapat meniadakan semua keuntungan metodologi. Memahami jebakan ini membantu tim menerapkan praktik dengan lebih efektif.

Tes terlalu besar

Anti-pola pertama dan paling umum — menguji terlalu banyak fungsionalitas dalam satu tes. Tes harus memeriksa tepat satu pernyataan (satu asersi). Jika tes gagal, pengembang harus tahu apa yang tepatnya rusak tanpa debugging tambahan.

Mengabaikan fase merah

Kesalahan kedua — menulis tes yang langsung lolos. Jika tes tidak pernah merah setidaknya sekali, tidak ada kepastian bahwa tes tersebut benar-benar memeriksa sesuatu. Aturan: jangan pernah percaya pada tes yang belum pernah Anda lihat gagal.

Melewatkan refactoring

Kesalahan umum ketiga — berhenti di fase hijau. Refactoring bukanlah tahap opsional, melainkan wajib dalam siklus. Tanpanya, basis kode menurun, tes menjadi rapuh, dan keuntungan TDD hilang.

  • Menguji implementasi, bukan perilaku — tes terikat pada detail dan rusak pada setiap refactoring
  • Tidak adanya tes untuk kasus tepi — daftar kosong, nilai null, kondisi batas tetap tidak tercover
  • Mengabaikan kecepatan tes — tes lambat memperlambat umpan balik dan membunuh disiplin TDD

Pertanyaan yang Sering Diajukan

TDD — teknik pengujian atau desain?

TDD pertama-tama adalah teknik desain, bukan teknik pengujian. Tes dalam TDD berperan sebagai spesifikasi: mereka menentukan API komponen sebelum implementasinya. Kent Beck sendiri menyebut TDD “disiplin desain, bukan disiplin pengujian”.

Berapa lama waktu yang dibutuhkan untuk menguasai TDD?

Menurut penelitian Microsoft Research, tim membutuhkan 3 hingga 6 bulan praktik terus-menerus agar TDD menjadi kebiasaan. 2–3 minggu pertama produktivitas turun 15–30%, tetapi setelah adaptasi kembali ke tingkat awal atau melampauinya berkat pengurangan waktu debugging.

Apakah TDD cocok untuk komponen UI?

Ya, tetapi dengan batasan. Untuk logika UI (ViewModel, State) TDD dapat diterapkan langsung. Untuk komponen visual (Compose UI, SwiftUI Views) pengujian snapshot (snapshot testing) melengkapi TDD, tetapi tidak menggantikannya. Disarankan untuk memisahkan logika bisnis dan presentasi.

Bisakah TDD diterapkan di proyek legacy?

Untuk kode legacy, strategi “tes karakterisasi” (characterization tests) direkomendasikan — ketika tes ditulis pada perilaku yang ada, kemudian kode direfaktor. Pendekatan ini dijelaskan dalam buku Michael Feathers “Working Effectively with Legacy Code” (2004) dan memungkinkan penerapan TDD secara bertahap.

Bagaimana TDD berpadu dengan Clean Architecture?

TDD dan Clean Architecture saling memperkuat. Arsitektur bersih membutuhkan batasan yang jelas antar lapisan, dan TDD memaksa pengembang untuk merancang batasan tersebut melalui tes. Lapisan domain diuji secara terisolasi dengan dependensi mock, lapisan data — melalui tes integrasi.

Kesimpulan

  • TDD — metodologi di mana tes ditulis sebelum implementasi, membentuk API yang bersih dan mengarahkan arsitektur
  • Siklus Red-Green-Refactor — unit dasar TDD: tes gagal → implementasi minimal → refactoring
  • Penerapan TDD mengurangi kepadatan cacat sebesar 40–90% menurut penelitian IBM dan Microsoft Research
  • Alat utama untuk Android: JUnit 5, MockK, Turbine untuk Flow
  • MockK lebih disukai daripada Mockito di proyek Kotlin berkat dukungan coroutine dan sealed class
  • Kesalahan umum: tes terlalu besar, melewatkan fase merah, mengabaikan refactoring
  • Strategi penerapan yang direkomendasikan — bertahap, dimulai dari lapisan domain dan fitur baru, tanpa mencakup semua kode legacy sekaligus

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga