Teknik Test-Driven Development

Kezia Sulami
6 min readApr 4, 2021

--

Tiga tahapan pada TDD: Red, Green, dan Refactor

Pendahuluan

Test-Driven Development (TDD) merupakan suatu proses pengembangan software dengan cara membuat test terlebih dahulu. TDD dipopulerkan oleh Kent Beck, seorang software engineer asal Amerika Serikat. Beliau sempat mengeluarkan pernyataan yang menarik mengenai TDD, yaitu bahwa TDD menghasilkan perangkat lunak yang simpel dan inspires confidence!

Tujuan TDD

Tujuan TDD adalah menghasilkan kode yang jelas, simpel, dan bebas bug. Software yang dihasilkan juga menjadi lebih reliabel karena coverage yang tinggi menunjukkan bahwa developer paham dengan kode yang dibuat.

Manfaat TDD

Image Source: https://dev.to/lypchenko/test-driven-development-method-and-how-to-use-it-4l2f

Sesuai dengan tujuan dari TDD di atas, TDD menghasilkan manfaat berikut:

  • Kode yang modular artinya fungsionalitas yang berbeda diletakkan pada modul yang berbeda. Hal ini sejalan dengan tujuan TDD karena jika setiap modul memiliki fungsi masing-masing, maka kode lebih jelas dan simpel. Mencari bug juga menjadi lebih mudah yaitu pada modul yang terkait.
  • Lebih mudah di-maintain. TDD menghasilkan kode yang berkualitas lebih baik (karena sudah pass test terlebih dahulu) sehingga melakukan maintainance pada kode menjadi lebih mudah. Selain itu, kita bisa yakin bahwa kode yang baru tidak akan merusak kode yang lama jika ia berhasil melalui test yang sudah ada.
  • Mempererat kolaborasi tim. Tim dapat mengadakan pertemuan singkat untuk membahas kode termasuk test serta best practices untuk membuat test yang lebih efektif, sehingga kolaborasi pada tim menjadi lebih erat.
  • Mencegah bug. Hal ini karena implementasi kode dibuat berdasarkan test yang sudah ada. Artinya kita sudah mengetahui ekspektasi behavior-nya ingin seperti apa. Jika test dibuat dengan baik (termasuk positive case dan negative case), maka kode yang pass test tidaklah buggy.
  • Memungkinkan perubahan yang cepat. TDD merupakan siklus yang terdiri atas fase membuat test, membuat kode yang pass test tersebut, dan refactor. TDD memungkinkan perubahan yang cepat karena tidak perlu langsung membuat test yang besar dan implementasi kode yang besar pula untuk menjalankan TDD, melainkan kecil-kecil saja tetapi mengikuti kaidah TDD yaitu RED-GREEN-REFACTOR.

TDD vs No TDD

Implementasi yang dibuat oleh seorang developer mungkin saja mengandung kesalahan (bug). Dengan melakukan TDD, kesalahan tersebut akan terdeteksi karena implementasi yang salah tidak akan lolos test. Tanpa melakukan TDD, kesalahan tersebut tidak terdeteksi karena tidak membuat test sebelumnya. Pendekatan No TDD mungkin awalnya terasa cepat karena deployment dapat langsung dilakukan tanpa perlu membuat test. Namun, seiring berjalannya waktu, bug tersebut dapat terus bertambah. Pada akhirnya, pendekatan TDD akan menghasilkan software yang berkualitas lebih baik dan mendukung kehidupan developer yang lebih baik pula, seperti pada ilustrasi berikut:

Image Source: http://turnoff.us/geek/tdd-vs-ftt/

Tahapan TDD

Ketika mengembangkan software dengan TDD, berikut adalah prosesnya:

Red: Write a failing test

Pada tahap pertama, kita menuliskan test untuk kode kita nantinya. Karena ini merupakan tahap pertama dan implementasi kodenya belum dibuat, maka test tersebut pasti akan fail. Test merupakan kasus uji yang berisi ekspektasi behavior dari implementasi nantinya harus seperti apa. Berikut saya akan mencantumkan contoh konkret dari test yang saya buat:

Apabila diterjemahkan dalam bahasa manusia, test tersebut berbunyi:

  • URL /api/cities/1: status HTTP 200 OK, dan URL tersebut harus mengembalikan data kota Jakarta dengan tiga buah atribut.
  • URL /api/cities/50005: status failed (karena data kota yang disimpan tidak sampai 50005), dengan error message City doesn’t exist.

Green: Make the test pass

Laluilah test yang sudah kita buat sendiri dengan cara mengimplementasikan kode sedemikian sehingga behavior-nya sesuai dengan ekspektasi pada test. Berikut adalah contoh konkret dari implementasi berdasarkan test di atas:

Mari kita terjemahkan ke bahasa manusia lagi, dari baris 50 yaitu try. Jadi, coba dapatkan object city dengan id sesuai yang diinginkan. Jika object ada maka kembalikan response berupa data object city tersebut. Namun jika object tidak ada maka akan terjadi exception Object Does Not Exist. Pada kasus tersebut kita kembalikan response dengan status failed, kote HTTP 404 (not found), dan error message City doesn’t exist, sesuai ekspektasi pada test.

Refactor

Refactoring pada dasarnya merupakan kegiatan perbaikan struktur internal kode tanpa mengubah behavior eksternal. Misal: mengubah nama variabel, nama method, dan nama class supaya lebih deskriptif. Contoh lain adalah menghapus duplikasi kode, memindahkan method ke tempat yang tepat.

[REFACTOR] Melakukan extract method untuk mengatasi duplikasi kode

Pada TDD, kita perlu me-refactor sesuai keperluan agar kode yang dihasilkan tidak hanya benar (memenuhi test) melainkan struktur internalnya juga baik. Refactoring di atas apabila diterjemahkan ke dalam bahasa manusia berarti membuat fungsi yang melakukan konversi dari string menjadi list. Oleh karena itu, fungsi tersebut diberi nama toList yang menerima input sebuah string. Awalnya konversi dilakukan secara inline pada masing-masing baris. Karena sekarang sudah dibuat fungsi, maka fungsi tersebut tinggal dipanggil.

Three Laws of TDD

Secara lebih formalnya, ketika kita ingin mengembangkan perangkat lunak dengan proses TDD yang benar, terdapat tiga hukum yang harus dipenuhi:

First Law. You may not write production code until you have written a failing unit test. Ini ekuivalen dengan: kita boleh menulis kode implementasi hanya jika kita sudah menuliskan testnya (tentu fail karena belum diimplementasi).

Second Law. You may not write more of a unit test than is sufficient to fail, and not compiling is failing. Artinya menuliskan failing test-nya secukupnya dulu saja. Bayangkan jika langsung menulis 1000 failing test, sungguh tidak patut.

Third Law. You may not write more production code than is sufficient to pass the currently failing test. Kita mengimplementasikan kode hanya untuk memenuhi test, tidak lebih. Untuk implementasi selanjutnya, buat test terlebih dahulu.

Perhatikan bahwa dengan memenuhi ketiga hukum TDD ini, kita membuat test secukupnya, dan membuat implementasi kode secukupnya untuk memenuhi test. Implikasinya adalah siklus TDD ini tidak panjang, kita bisa cepat dari Red ke Green, ke Red, ke Green lagi, dst. Sesekali refactor ketika diperlukan. Selain itu, seluruh implementasi akan ter-cover 100% oleh test.

Bagaimana TDD membantu kehidupan developer?

Bayangkan kita sedang mengerjakan proyek bersama teman. Sudah jadi tiga fitur dan kita sedang mengerjakan fitur keempat. Apabila tidak ada test yang dibuat, bagaimana saya yakin kode saya tidak akan menghancurkan sebagian kecil (atau besar) kode teman saya dan kode saya sebelumnya? Melakukan coding proyek tanpa test benar-benar tak terbayangkan apabila kita sudah berkenalan dengan TDD dan merasakan manfaatnya.

Pernyataan Mr. Kent Beck mengenai TDD yang inspires confidence tadi benar-benar tepat. Dengan asumsi seluruh anggota tim saya melakukan TDD dengan benar (artinya test men-cover 100% implementasi kode secara sempurna), saya bisa yakin bahwa kode baru yang saya buat tidak merusak kode sebelumnya apabila ia tidak menggagalkan test, karena testnya kokoh. Agar tidak hanya berasumsi, implementasikan TDD bersama tim kalian!

TDD juga membantu kita memahami kode dengan lebih baik. Hal ini karena kita tahu dengan jelas ekspektasinya seperti apa, dan mengimplementasikan kode untuk memenuhi ekspektasi tersebut. Ini membuat ekspektasi terhadap kode menjadi jelas. Maka, tidak heran jika kode yang dihasilkan berkualitas.

Commit message untuk TDD

Ketika kita mengembangkan software menggunakan TDD lalu kita ingin commit dan push ke repositori Git online, jangan lupa untuk menambahkan tag [RED] / [GREEN] / [REFACTOR] pada commit message, seperti pada gambar di bawah. Alasannya adalah agar lebih deskriptif, jadi ketika sedang melihat daftar seluruh commit yang ada, bisa dengan mudah diketahui suatu commit berada di fase RED atau GREEN atau REFACTOR. Selain itu, menuliskan tag pada commit message juga membantu meningkatkan pemahaman kita terhadap commit kita sendiri. Apabila tidak menggunakan tag tersebut, seolah-olah kita tidak tahu yang kita push itu akan RED atau GREEN, akan sukses melalui pipeline atau gagal. Dengan menambahkan tag pada commit message, kita meningkatkan awareness terhadap kode kita sendiri. (minimal memahami akan melalui pipeline dengan RED atau GREEN)

Pertama [RED], lalu diikuti [GREEN]. Jika perlu, lakukan [REFACTOR]

Kesimpulan

TDD merupakan teknik pengembangan software dimana kita membuat test sebelum membuat implementasi. Dengan melakukan TDD, kita dapat merasa yakin bahwa seluruh implementasi yang sudah lulus test artinya behavior implementasi tersebut sudah sesuai ekspektasi. Hal ini tentu dapat meningkatkan kepercayaan diri kita dalam mengembangkan software, seperti yang diutarakan oleh Kent Beck yang mencetuskan TDD.

Terima kasih!

Referensi

--

--