Test-Driven Development

Abdurrahman Luqmanul Hakim
7 min readMay 2, 2021

--

This article was created for the purpose of individual review assignment of PPL 2021

Dalam menuliskan code, seorang developer terkadang juga harus membuat sebuah test code untuk menguji apakah production code yang dia buat sudah berjalan dengan benar. Test code ini akan menjalankan production code dengan memanggil fungsi-fungsi dan class-class didalamnya. Seorang developer mungkin terkadang akan membuat test code setelah selesai membuat production code, dan hanya menjalankannya untuk memastikan bahwa production code yang dibuat tidak ada masalah. Mungkin juga beberapa orang membuat test code seiring dengan pembuatan production code. Pada artikel ini saya akan membahas tentang Test-Driven Development, atau bisa disingkat menjadi TDD, yang merupakan suatu konsep atau cara dalam penulisan test code tersebut.

Pengertian dari TDD

Test-Driven Development adalah suatu pendekatan dalam menuliskan suatu software, dimana test cases dibuat terlebih dahulu sebelum mulai menuliskan production code, dan dikembangkan untuk menjelaskan dan memvalidisi apa yang akan dilakukan oleh production code. Secara singkat, TDD mengharuskan untuk membuat test cases terlebih dahulu, dimana test case tersebut akan dijalankan untuk di uji coba. Jika test case tersebut gagal, production code baru akan dibuat untuk meluluskan test tersebut. Untuk mendapatkan gambaran lebih jelas, berikut ini adalah 3 prinsip dari TDD yaitu:

  1. Kita tidak boleh menuliskan production code sampai kita menuliskan unit test yang gagal.
  2. Kita tidak boleh menuliskan unit test yang lebih dari cukup untuk gagal, dan tidak mengkompilasi berarti kegagalan.
  3. Kita tidak boleh menuliskan unit test yang lebih dari cukup untuk meluluskan unit test yang sedang gagal.

Alur penerapan TDD

3 prinsip TDD yang disebutkan diatas menjadi aturan untuk tahapan dalam melakukan TDD dibawah.

TDD Cycle — source: Slide PPW materi Test-Driven Development Fakultas Ilmu Komputer UI

Tahapan yang harus dilakukan dalam melakukan TDD biasa disebut sebagai TDD cycles. Tahapan ini bisa dibagi menjadi 3 fase, yaitu:

  1. RED: Tahapan untuk menuliskan test case yang gagal/tidak lulus ketika dijalankan. Test case ini jelas tidak akan lulus karena production code yang diuji coba belum dibuat.
  2. GREEN: Membuat production code yang akan meluluskan test case yang telah dibuat sebelumnya. Production code yang dibuat pada tahap ini biasanya masih dibuat seminimal mungkin, namun cukup untuk lulus pada test case.
  3. REFACTOR: Production code yang telah dibuat di tahap sebelumnya dikembangkan lebih lanjut jika dibutuhkan. Production code akan di refine sehingga pengimplementasian code yang dibuat sebelumnya akan lebih bagus, baik dari segi struktur, performa, ataupun penulisan. Biasanya hal yang diubah terkait masalah duplikasi yang dibuat untuk meluluskan test sebelumnya. Code yang telah dikembangkan ini tetap harus dipastikan akan lulus test (tidak kembali ke RED).

Tujuan dan Manfaat menggunakan TDD

Programming is like exploring a dark house. You go from room to room to room. Writing the test is like turning on the light. Then you can avoid the furniture and save your shins (the clean design resulting from refactoring). Then you’re ready to explore the next room”

— Kent Beck, pembuat extreme programming

Jika dilihat secara sekilas, mungkin beberapa orang akan berpikir bahwa pembuatan test bisa dilakukan kapan saja, baik sebelum atau sesudah pembuatan test code, selama production code yang dibuat sudah diuji coba dan dengan test cases masing-masing. Namun sebenarnya penerapan TDD punya banyak tujuan dan manfaatnya sendiri, beberapa diantaranya yaitu:

  1. Menghindari duplikasi dari code.

Dalam penerapan TDD, kita diperbolehkan untuk menuliskan production code hanya ketika sudah ada test case yang gagal. Hal ini dapat mencegah terjadinya duplikasi code, karena production code yang dibuat hanya sedikit dalam satu waktu untuk meluluskan test case, sehingga kemungkinan kita menuliskan code yang melakukan pekerjaan yang sama rendah. Selain itu, pada refactor, setiap duplikasi yang ada pada code yang dibuat untuk meluluskan test juga akan diperiksa dan dieliminasi.

2. Mendapat gambaran yang lebih jelas tentang apa yang diinginkan dari code.

Dengan membuat test case sebelum production code, kita bisa mendapat gambaran lebih jelas mengenai code yang akan dibuat. Hal ini dikarenakan saat menuliskan test kita harus memikirkan dengan jelas mengenai apa yang kita inginkan dari code tersebut.

3. Dapat mengidentifikasi bugs dan error lebih cepat.

Dengan membuat test case, kita bisa lebih aware terhadap bug dan error apa saja yang mungkin terjadi pada production code yang akan dibuat.

4. Dapat mengurangi waktu dalam mengerjakan code kembali.

Karena production code yang dibuat hanya untuk meluluskan test, sehingga akan mengurangi kemungkinan pembuatan code yang tidak penting, dan kemungkinan code diubah kembali pun akan rendah. Selain itu tahap refactor juga akan lebih me refine code sehingga code tidak perlu dirombak kembali.

5. TDD dapat berperan sebagai spesifikasi dan dokumentasi dari code.

Test cases dalam TDD menguji coba semua fungsi dari production code yang kita buat. Jadi sebenarnya dengan menjalankan melihat alur dari test cases tersebut, kita bisa mendapatkan gambaran semua fungsi dari production code yang telah kita buat.

Contoh Implementasi dari TDD

Pada bagian ini, saya akan menunjukan sedikit contoh implementasi dari TDD pada salah satu project yang saya buat. Gambar dibawah merupakan contoh salah satu test case yang ada pada project saya.

salah satu contoh test case

Test case diatas akan mencoba untuk login pada session, sebelum dia memanggil url routing tertentu, dan mengecek apakah response yang didapat merupakan HTTP status code 200 ok, menandakan HTTP requests berhasil. Test case diatas tentunya akan gagal, karena saya seharusnya belum membuat fungsi views yang digunakan, jangankan membuat routing url pada alamat tersebut. Pembuatan 1 test case ini sendiri merupakan tahap RED pada TDD. Berikut adalah hasil yang didapatkan ketika saya melakukan push terhadap code ke repository project saya di Gitlab.

contoh gitlab pipeline pada tahap RED

Kemudian setelah tahap RED selesai, saya membuat code yang akan meluluskan test case tersebut sebagai berikut.

url routing yang akan mengakses fungsi my_profile
fungsi yang akan dipanggil oleh test case, yaitu my_profile

Gambar pertama merupakan url routing yang jika diakses akan memanggil fungsi my_profile() pada gambar kedua. Kemudian fungsi tersebut pun akan mengembalikan HTTP response 200, sesuai dengan yang diperiksa pada test case.Jika saya mencoba melakukan push terhadap code ke repository project saya di Gitlab, akan menghasilkan pipeline berikut.

contoh gitlab pipeline pada tahap GREEN

Tentunya fungsi diatas bukanlah fungsi jadi akhir yang saya gunakan pada projek saya, sehingga masih bisa dilakukan refactor untuk fungsi tersebut. Jika dilihat fungsi tersebut hanya akan mengembalikan response dengan status 200 yang berarti OK / request telah berhasil, namun tidak mengembalikan halaman apapun. Maka dari itu, saya dapat melakukan refactor sehingga fungsi tersebut akan mengembalikan sebuah halaman html dan tetap GREEN / lulus test. Pertama saya harus menambahkan file html terlebih dahulu pada project, misalkan dengan nama “my_profile.html”. Lalu fungsi diatas akan saya modifikasi lebih lanjut menjadi sebagai berikut:

fungsi my_profile yang telah dilakukan refactor

Fungsi diatas akan tetap lulus test yang telah dibuat karena jika fungsi berhasil mengembalikan sebuah halaman akan memiliki status 200. Namun fungsi diatas sudah melakukan hal yang lebih dari fungsi sebelumnya, yaitu dia mengembalikan sebuah halaman html untuk requests.

Maka dari itu, proses REFACTOR dari fungsi selesai. Jadi 1 TDD cycle harusnya telah selesai. Berikut adalah sedikit contoh dari pipeline gitlab hasil dari proses TDD yang saya lakukan, yang dilihat dari bawah keatas.

contoh pipeline-pipeline hasil proses TDD

Kekurangan dalam menggunakan TDD

Dalam proses pengimplementasian TDD pada projek saya, selain mendapatkan keuntungan, saya juga merasakan beberapa hal mengganggu saya dalam proses development. Hal-hal ini mungkin sebagian besar disebabkan karena kurangnya pengalaman saya dalam pengimplementasian TDD, sehingga saya pun masih belum familiar terhadap penggunannya. Berikut beberapa hal yang saya rasa tersebut:

  1. Menghambat proses development jika pengetahuan mengenai TDD kurang.

Seperti yang disebutkan sebelumnya, pengalaman saya terhadap TDD masih minim. Hal ini mengakibatkan terhambatnya proses pengembangan projek saya, dikarenakan saya masih mencari tahu test case bagaimana yang harus saya buat untuk code yang akan saya kerjakan. Meskipun saya sudah tahu apa yang harus saya lakukan dalam menuliskan production code, karena test case yang diperlukan untuk product code tersebut belum jadi, saya pun belum bisa menuliskan production code tersebut, sehingga proses pengembangan projek pun sering terhambat.

2. Adanya penambahan code yang harus ditulis.

Tentunya meskipun test code dibuat untuk menguji production code, test code itu sendiri merupakan sebuah code. Jadi, bisa dibilang selain harus menuliskan production code, saya juga harus menuliskan code tambahan diluar production code tersebut.

3. Test code harus diubah ketika ada perubahan pada production code

Misalkan ada kesalahan atau perubahan besar pada production code, tentunya test code juga harus ikut diubah juga. Jadi bahkan sebelum kita bisa mengubah production code itu sendiri, kita harus mengubah semua test case terkait production code tersebut. Seperti contoh, pada project yang saya buat, ada perubahan besar terhadap model-model yang digunakan pada project, sehingga saya pun harus mengubah semua fungsi dan test case yang berhubungan dengan model-model tersebut.

Sekian artikel yang saya buat mengenai TDD, terima kasih.

--

--