Testing First: The Power of Test-Driven Development

Ivan Phanderson
7 min readMar 16, 2023

--

Sumber

Apa itu TDD?

TDD merupakan singkatan dari Test Driven Development yang merupakan salah satu teknik pengembangan software yang didahului dengan menulis test terlebih dahulu baru diikuti dengan menulis source code untuk fitur tersebut. Berikut merupakan langkah-langkah dalam TDD:

  • Menulis test (positive test dan negative test) untuk menguji kesesuaian source code kita terhadap requirements, test di sini pasti akan gagal karena belum diimplementasikan source code-nya
  • Menulis source code untuk fitur tersebut
  • Menjalankan test
  • Jika semua test berhasil, maka source code kita sudah memenuhi requirements dari fitur tersebut
  • Jika ada test yang gagal, maka refactor source code tersebut agar memenuhi requirements
  • Ulangi langkah-langkah di atas untuk fitur lainnya atau jika terdapat perubahan requirements dari fitur tersebut

Kelebihan dan Kekurangan TDD

Setiap teknik pengembangan software tentu saja memiliki kelebihan dan kekurangannya masing-masing. Berikut merupakan kelebihan dari teknik TDD:

  • Kualitas kode lebih tinggi karena kita dapat mengidentifikasi apakah kode kita memenuhi requirements dari awal.
  • Test coverage lebih baik karena test yang ditulis terlebih dahulu sehingga mengharuskan developers menulis source code yang sesuai test tersebut. Selain itu, TDD yang baik juga memastikan bahwa fitur tersebut diuji secara menyeluruh
  • Lebih mudah melakukan refactoring karena jika kita tidak sengaja mengubah fungsionalitasnya menjadi tidak sesuai requirements, maka akan terlihat dari test yang fail

Dibalik kelebihan TDD, juga ada kekurangan dari TDD. Berikut merupakan beberapa kekurangan TDD:

  • Menulis test sebelum menulis kode biasanya akan memerlukan waktu yang lebih lama.
  • Cukup sulit untuk dipelajari bagi developers yang terbiasa menulis kode sebelum menulis test
  • Terlalu merasa aman ketika menulis kode. TDD membantu kita untuk menemukan bug ketika menulis source code. Akan tetapi, kode kita belum tentu bersih dari bug walaupun kita berhasil melewati semua testnya.

Kriteria Test yang Baik

Dalam menulis test saat TDD, terdapat beberapa kriteria yang sebaiknya dipenuhi agar kode bagian testing kita lebih berkualitas. Berikut adalah beberapa kriterianya:

  • Isolated. Sebuah test sebaiknya tidak bergantung pada test lain
  • Specific. Sebuah test yang baik harus bersifat spesifik memeriksa satu hal saja
  • Mudah dipahami. Kode test harus ditulis dengan rapi sehingga mudah dipahami oleh siapa saja. Salah satu caranya adalah dengan menggunakan nama yang deskriptif untuk setiap method yang dibuat.
  • Fast. Test kita harus berjalan dengan cepat agar tidak memperlambat proses pengembangan software.
  • Lengkap. Kode test tidak hanya mencakup skenario sukses saja, tetapi seluruh kemungkinan (seperti edge case) harus dipertimbangkan
  • Maintainable. Kode test harus dapat diubah dengan mudah jika terdapat perubahan requirements dari suatu fitur.

Best Practice dalam TDD

Ketika menggunakan teknik TDD untuk mengembangkan software, terdapat beberapa best practice yang sebaiknya diikuti agar kode kita lebih berkualitas. Berikut adalah beberapa best practice dalam TDD:

  1. Memulai dengan menulis test yang gagal. Artinya, kita menulis test terlebih dahulu pada fitur yang belum diimplementasi atau pada bug yang belum dibenahi agar source code pada bagian tersebut bekerja sesuai ekspektasi. Pastikan juga test yang ditulis memenuhi kriteria test yang baik seperti pada penjelasan di atas
  2. Menulis source code sesederhana mungkin yang dapat melewati test tersebut. Kode yang sederhana akan memudahkan developers untuk memahami, mengelola, dan melakukan refactor
  3. Setelah berhasil melewati seluruh test, lakukan refactor agar desain kode kita lebih baik dan mengurangi duplikasi pada kode.
  4. Jalankan test secara rutin setiap melakukan perubahan pada source code untuk memastikan bahwa kode kita berjalan sesuai ekspektasi
  5. Gunakan bantuan analisis code coverage untuk memastikan bahwa seluruh source code kita memang sudah di-test oleh kode bagian testing.
  6. Selalu mengevaluasi strategi testing berdasarkan hasil testing dan feedbacknya untuk memastikan bahwa software kita berjalan dengan efektif dan efisien

Red-Green-Refactor pada TDD

Sumber

Salah satu pendekatan yang paling populer dalam TDD adalah pendekatan Red, Green, Refactor. Pendekatan ini sering digunakan karena pendekatannya sederhana, jelas, dan efektif dalam pengembangan software menggunakan TDD.

Red

Fase ini selalu menjadi fase awal sebelum masuk ke fase green dan refactor. Tujuan dari fase ini adalah menulis test untuk ekspektasi dari implementasi suatu fitur. Test ini hanya akan pass jika ekspektasinya terpenuhi. Akan tetapi, Mengingat test yang ditulis terlebih dahulu sebelum working codenya, maka test yang ditulis pada fase ini pasti akan fail.

Green

Fase ini adalah lanjutan dari fase red dimana kita mulai mengimplementasikan working code dari test yang dibuat pada fase red. Tujuan dari fase ini adalah memastikan bahwa seluruh test yang fail pada fase red berubah menjadi passed.

Refactor

Setelah melakukan implementasi, kadang kita ingin melakukan optimisasi atau penyederhanaan dari kode kita. Proses ini disebut refactor karena kita hanya mengubah kode kita tanpa mengubah perilakunya (test harus tetap pass). Setelah melakukan proses ini, kita dapat kembali ke proses menulis test kembali (fase red). Fase ini dilakukan secara iteratif.

Implementasi TDD pada PPL

[RED]

Positive test
Negative test

Pada fase ini, saya melakukan implementasi test untuk PBI yang saya ambil yaitu read, update, dan delete akun. Contoh di atas merupakan contoh implementasi positive test dan negative test untuk bagian update akun.

[GREEN]

Setelah menulis test, saya melakukan implementasi update akun dengan memastikan bahwa seluruh testnya passed.

[REFACTOR]

Setelah melakukan implementasi, terdapat beberapa code smell pada Sonarqube kelompok. Oleh karena itu, saya melakukan refactor menjadi seperti pada kode di atas, yaitu memisahkan fungsi yang meng-handle method GET dan method POST.

Advanced TDD

Test Doubles

Test doubles merupakan test yang meniru perilaku objek lain dalam sistem untuk mengisolasi kode yang sedang diuji. Biasanya test doubles digunakan untuk mensimulasikan dependensi yang bergantung pada kode yang sedang diuji seperti database, koneksi ke API eksternal, dan lain-lain. Terdapat 5 tipe test doubles, yaitu:

  1. Dummy: Objek dummy adalah objek placeholder yang digunakan sebagai pengganti objek nyata dalam test. Objek dummy sering digunakan ketika sebuah objek diperlukan dalam parameter untuk sebuah method, tetapi method tersebut tidak menggunakan objeknya dengan cara yang berarti.
  2. Stub: Stub adalah pre-programmed response terhadap suatu pemanggilan method spesifik. Stub digunakan untuk mengganti objek nyata dengan versi yang lebih sederhana. Biasanya stub dipakai ketika kita ingin mensimulasikan error atau membuat data test yang dapat diprediksi.
  3. Spy: Objek spy memungkinkan kita untuk melacak perilaku objek ketika testing. Spy sering digunakan untuk memverifikasi apakah suatu method dipanggil dengan argumen yang benar atau untuk memverifikasi berapa kali suatu method dipanggil.
  4. Mock: Objek mock adalah objek yang mensimulasikan perilaku dari objek nyata. Biasanya mock dipakai untuk mensimulasikan perilaku dari objek yang sulit dibuat seperti API eksternal.
  5. Fake: Fake merupakan implementasi yang lebih sederhana dari objek yang sebenarnya dalam sebuah test. Fake dapat digunakan ketika kita ingin menguji koneksi database tanpa benar-benar terhubung ke database sebenarnya.

Integrasi Test Dengan CI/CD GitLab

Continuous Integration (CI) dan Continuous Delivery/Deployment (CD) adalah praktik pengembangan software yang berfokus pada automasi proses build, testing, dan deployment suatu software. Setiap kali kita melakukan perubahan pada kode kita, maka secara otomatis pipeline CI/CD akan berjalan. Hal ini memastikan setiap perubahan akan ditest secepat mungkin sehingga setiap error atau bugs dapat diketahui dan diselesaikan dengan cepat. GitLab juga menyediakan CI/CD yang dapat kita konfigurasi menggunakan file .gitlab-ci.yml. Script untuk menjalankan test secara otomatis pada pipeline GitLab untuk aplikasi berbasis Django adalah sebagai berikut:

test:
image: python:3.8.8
stage: test
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
before_script:
- if [[ $CI_COMMIT_REF_NAME == master ]]; then ENVIRONMENT="PRODUCTION"; fi
- if [[ $CI_COMMIT_REF_NAME == staging ]]; then ENVIRONMENT="STAGING"; else ENVIRONMENT="DEVELOPMENT"; fi
- pip install -r requirements.txt
- python manage.py migrate
- python manage.py collectstatic --no-input
when: on_success
script:
- coverage run --include="./*/*" manage.py test
- coverage report -m
- coverage xml -i
artifacts:
paths:
- coverage.xml

Dengan menaruh script tersebut ke file .gitlab-ci.yml , maka GitLab secara otomatis akan menjalankan pipeline CI/CD untuk testing setiap kali kita melakukan push kode ke GitLab.

Kesimpulan

TDD merupakan teknik yang powerful yang dapat meningkatkan kualitas kode kita secara signifikan. Teknik ini memungkinkan kita untuk mengetahui bug dari awal dan mempermudah maintenance kode untuk jangka panjang melalui test yang dibuat. Dengan menggunakan teknik TDD, software yang kita hasilkan juga akan berkualitas tinggi dan memenuhi requirements dari klien.

--

--