Pada artikel kali ini, kita akan menerapkan paradigma pengembangan perangkat lunak Test Driven Development (TDD)
dan mengintegrasikannya dengan Git, tool yang digunakan untuk memantau kode program.
Aturan Main
Sebelum memulai praktik kita perlu mengetahui proses dalam TDD. Kent Beck, seorang pengembang perangkat lunak yang
juga mencetuskan Extreme Programming (XP), menulis demikian pada bukunya yang berjudul "Test Driven Development by
Example":
Quickly add a test
Run all tests and see the new one fail
Make a little change
Run all tests and see them all succeed
Refactor to remove duplication
Kita akan terus-menerus mengulangi langkah di atas. Perbedaan praktik dalam TDD dengan yang tidak pakai TDD adalah
kode tes harus dibuat lebih dulu sebelum kode solusi.
Selain itu Uncle Bob juga mengajukan tiga aturan dalam menjalankan TDD:
You are not allowed to write any production code unless it is to make a
failing unit test pass.
You are not allowed to write any more of a unit test than is sufficient
to fail; and compilation failures are failures.
You are not allowed to write any more production code than is sufficient
to pass the one failing unit test.
Intinya, TDD yang benar harus dijalankan satu per satu. Buat satu tes, disusul solusi untuk menyelesaikan satu tes
tersebut. Setiap langkah perlu diverifikasi. Kode tes harus selesai dibuat tepat setelah kode tersebut menghasilkan
kegagalan (ini menjamin hanya 1 assertion saja yang dibuat). Kode solusi cukup untuk menyelesaikan 1 test tersebut.
Setelah solusi berhasil mengubah 1 assertion menjadi sukses, buat lagi tes/assertion lainnya.
Keuntungan TDD
Menurut saya, TDD membuat developer terus-menerus menguji kodenya sehingga program yang dibuat betul-betul bisa
dipahami behaviournya.
Integrasi dengan Git
Untuk menerapkan TDD pada kode yang dipantau dengan Git, kita bisa melakukan hal-hal berikut:
Pastikan file untuk kode tes dan file untuk kode solusi terpisah
Lakukan commit untuk kode tes dan commit untuk kode solusi secara terpisah
Sama seperti pada umumnya, satu commit idealnya untuk satu pekerjaan. Dari daftar ini
kita dapat menjadikan [test] untuk kode tes dan [feat] untuk kode solusi. Jadi gara-gara pakai TDD, tidak harus setiap
satu tes atau assertion dibuat commit tersendiri.
Langsung saja kita praktikkan
Praktik: Instalasi
Kita akan menggunakan Python dan Git. Keduanya dapat diinstalasi dengan panduan di bawah:
Untuk memulai proyek, siapkan folder bernama praktik-tdd-git. Jalankan kedua line dibawah pada terminal/CMD:
mkdir praktik-tdd-git
cd praktik-tdd-git
Buat dua file Python bernama main.py dan test.py, lalu lakukan perintah git add -A pada terminal/CMD.
Pastikan kedua file muncul pada new file:
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: main.py
new file: test.py
Setelah itu lakukan git commit -m "initial commit" untuk melakukan commit pertama. Pastikan kedua file termasuk
dalam change (nomor setelah create mode dapat diabaikan)
Kita akan melakukan git add dan git commit lagi nanti.
Praktik: Membuat Unit Test
Kita akan membuat fungsi nilai faktorial:
Fungsi menerima sebuah teks input dan mengembalikan sebuah teks output
Jika input bukan numerik (mengandung karakter selain 0-9) program mengembalikan string Harap masukkan input numerik (0-9)
Jika input numerik, program mengembalikan Nilai faktorialnya adalah {x} dengan x adalah nilai faktorial dari
input. Misalnya, nilai faktorial 4 adalah 1x2x3x4=24 sehingga outputnya adalah Nilai faktorialnya adalah 24.
Karena kita menerapkan TDD, kita buat terlebih dahulu unit testnya. Buka test.py dan tuliskan kode berikut:
import unittest
class TestFaktorial(unittest.TestCase):
# We will implement the test here
if __name__ == "__main__":
unittest.main()
Coba jalankan python -m unittest test.py dan kompilasi masih sukses. Kita belum membuat satu pun unit test,
jadi mari kita buat:
class TestFaktorial(unittest.TestCase):
# We will implement the test here
def test_non_numeric_input(self):
self.assertEqual(faktorial("1.5"), "Harap masukkan input numerik (0-9)")
Nah, sekarang kita jalankan python -m unittest test.py dan assertion akan error karena kita belum buat fungsinya.
======================================================================
ERROR: test_non_numeric_input (test.TestFaktorial.test_non_numeric_input)
----------------------------------------------------------------------
NameError: name 'faktorial' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Kita harus berhenti membuat tes dan mulai membuat kode solusi.
Praktik: Membuat Kode Solusi
Sekarang mari kita buka main.py dan tuliskan kode berikut
def faktorial(user_input: str) -> str:
if not user_input.isnumeric():
return "Harap masukkan input numerik (0-9)"
Di sini fungsi faktorial menerima input string dan output string. Kita bisa menggunakan string method bawaan Python
isnumeric untuk memastikan input merupakan karakter numerik atau tidak.
Untuk membuat faktorial() bisa diakses kode tes, impor kode solusi ke dalam kode tes. Buka test.py lalu tambahkan
kode from main import faktorial pada line pertama
from main import faktorial
import unittest
Jalankan tes lagi: python -m unittest test.py. Seharusnya kali ini sudah berhasil:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Praktik: Membuat Unit Test Kedua
Kita bisa lanjutkan dengan membuat unit test berikutnya. Buka test.py lalu tambahkan kode di bawah test_non_ numeric_input
Test ini bertujuan untuk menguji apakah nilai faktorial yang dikembalikan benar. Nilai faktorial 0 adalah 1, kemudian
nilai faktorial berikutnya adalah perkalian dari 1x2x... sampai ke bilangan yang dituju.
Coba jalankan python -m unittest test.py, test akan gagal karena fungsi kita belum mengembalikan output hasil
faktorial.
AssertionError: None != 'Nilai faktorialnya adalah 24'
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
Praktik: Membuat Solusi untuk Test Kedua
Kembali buka main.py dan ketikkan kode solusi untuk bilangan faktorial
def faktorial(user_input: str) -> str:
if not user_input.isnumeric():
return "Harap masukkan input numerik (0-9)"
# Cast user_input string to integer
user_input = int(user_input)
result = 1
for i in range(1, user_input+1):
result *= i
return "Nilai faktorialnya adalah " + str(result)
Setelah memastikan input numerik, input pasti bisa dikonversi ke bilangan positif. Kita mulai dulu dari 1 karena
faktorial dari 0 adalah 1. Selanjutnya kita melakukan perkalian berulang 1x2x3x... pada for loop. Terakhir, kita
kembalikan hasilnya sebagai pesan string.
Simpan kode ini dan jalankan lagi python -m unittest test.py. Hasilnya akan kurang lebih seperti ini:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Terlihat bahwa kedua test telah OK.
Praktik: Menyimpan Perubahan pada Git
Kita akan membuat dua commit, yaitu untuk tes dan untuk solusi (implementasi). Untuk membuat commit pada tes lakukan
perintah ini pada terminal/CMD:
Pada commit pertama kita hanya menambahkan file-file yang digunakan untuk menulis unit test, yaitu pada praktik ini
test.py. Setelah menambahkan file tes, kita menuliskan pesan commit dengan awalan test: untuk menandakan bahwa ini
commit untuk test.
Selanjutnya lakukan perintah Git untuk kode solusi:
Perhatikan bahwa kini kita menambahkan file untuk solusi, yaitu main.py. Kita tuliskan pesan commit dengan awalan
feat: untuk menandakan pembuatan fitur baru.
Demikian panduan penerapan Test Driven Development (TDD) dengan Git. Semoga bermanfaat. Source code untuk
praktik di atas terdapat pada link berikut
Rujukan
Beck, K. (2003). Test-driven Development: By Example. Addison-Wesley Professional.
Pada artikel kali ini, kita akan menerapkan paradigma pengembangan perangkat lunak Test Driven Development (TDD) dan mengintegrasikannya dengan Git, tool yang digunakan untuk memantau kode program.
Aturan Main
Sebelum memulai praktik kita perlu mengetahui proses dalam TDD. Kent Beck, seorang pengembang perangkat lunak yang juga mencetuskan Extreme Programming (XP), menulis demikian pada bukunya yang berjudul "Test Driven Development by Example":
Kita akan terus-menerus mengulangi langkah di atas. Perbedaan praktik dalam TDD dengan yang tidak pakai TDD adalah kode tes harus dibuat lebih dulu sebelum kode solusi.
Selain itu Uncle Bob juga mengajukan tiga aturan dalam menjalankan TDD:
Intinya, TDD yang benar harus dijalankan satu per satu. Buat satu tes, disusul solusi untuk menyelesaikan satu tes tersebut. Setiap langkah perlu diverifikasi. Kode tes harus selesai dibuat tepat setelah kode tersebut menghasilkan kegagalan (ini menjamin hanya 1 assertion saja yang dibuat). Kode solusi cukup untuk menyelesaikan 1 test tersebut. Setelah solusi berhasil mengubah 1 assertion menjadi sukses, buat lagi tes/assertion lainnya.
Keuntungan TDD
Menurut saya, TDD membuat developer terus-menerus menguji kodenya sehingga program yang dibuat betul-betul bisa dipahami behaviournya.
Integrasi dengan Git
Untuk menerapkan TDD pada kode yang dipantau dengan Git, kita bisa melakukan hal-hal berikut:
Sama seperti pada umumnya, satu commit idealnya untuk satu pekerjaan. Dari daftar ini kita dapat menjadikan [test] untuk kode tes dan [feat] untuk kode solusi. Jadi gara-gara pakai TDD, tidak harus setiap satu tes atau assertion dibuat commit tersendiri.
Langsung saja kita praktikkan
Praktik: Instalasi
Kita akan menggunakan Python dan Git. Keduanya dapat diinstalasi dengan panduan di bawah:
Praktik: Memulai Git Repository
Untuk memulai proyek, siapkan folder bernama
praktik-tdd-git
. Jalankan kedua line dibawah pada terminal/CMD:Buat dua file Python bernama main.py dan test.py, lalu lakukan perintah
git add -A
pada terminal/CMD. Pastikan kedua file muncul pada new file:Setelah itu lakukan
git commit -m "initial commit"
untuk melakukan commit pertama. Pastikan kedua file termasuk dalam change (nomor setelah create mode dapat diabaikan)Kita akan melakukan
git add
dangit commit
lagi nanti.Praktik: Membuat Unit Test
Kita akan membuat fungsi nilai faktorial:
Harap masukkan input numerik (0-9)
Nilai faktorialnya adalah {x}
dengan x adalah nilai faktorial dari input. Misalnya, nilai faktorial 4 adalah 1x2x3x4=24 sehingga outputnya adalahNilai faktorialnya adalah 24
.Karena kita menerapkan TDD, kita buat terlebih dahulu unit testnya. Buka
test.py
dan tuliskan kode berikut:Coba jalankan
python -m unittest test.py
dan kompilasi masih sukses. Kita belum membuat satu pun unit test, jadi mari kita buat:Nah, sekarang kita jalankan
python -m unittest test.py
dan assertion akan error karena kita belum buat fungsinya.Kita harus berhenti membuat tes dan mulai membuat kode solusi.
Praktik: Membuat Kode Solusi
Sekarang mari kita buka
main.py
dan tuliskan kode berikutDi sini fungsi faktorial menerima input string dan output string. Kita bisa menggunakan string method bawaan Python isnumeric untuk memastikan input merupakan karakter numerik atau tidak.
Untuk membuat faktorial() bisa diakses kode tes, impor kode solusi ke dalam kode tes. Buka
test.py
lalu tambahkan kodefrom main import faktorial
pada line pertamaJalankan tes lagi:
python -m unittest test.py
. Seharusnya kali ini sudah berhasil:Praktik: Membuat Unit Test Kedua
Kita bisa lanjutkan dengan membuat unit test berikutnya. Buka
test.py
lalu tambahkan kode di bawahtest_non_ numeric_input
Test ini bertujuan untuk menguji apakah nilai faktorial yang dikembalikan benar. Nilai faktorial 0 adalah 1, kemudian nilai faktorial berikutnya adalah perkalian dari 1x2x... sampai ke bilangan yang dituju.
Coba jalankan
python -m unittest test.py
, test akan gagal karena fungsi kita belum mengembalikan output hasil faktorial.Praktik: Membuat Solusi untuk Test Kedua
Kembali buka
main.py
dan ketikkan kode solusi untuk bilangan faktorialSetelah memastikan input numerik, input pasti bisa dikonversi ke bilangan positif. Kita mulai dulu dari 1 karena faktorial dari 0 adalah 1. Selanjutnya kita melakukan perkalian berulang 1x2x3x... pada for loop. Terakhir, kita kembalikan hasilnya sebagai pesan string.
Simpan kode ini dan jalankan lagi
python -m unittest test.py
. Hasilnya akan kurang lebih seperti ini:Terlihat bahwa kedua test telah OK.
Praktik: Menyimpan Perubahan pada Git
Kita akan membuat dua commit, yaitu untuk tes dan untuk solusi (implementasi). Untuk membuat commit pada tes lakukan perintah ini pada terminal/CMD:
Pada commit pertama kita hanya menambahkan file-file yang digunakan untuk menulis unit test, yaitu pada praktik ini
test.py
. Setelah menambahkan file tes, kita menuliskan pesan commit dengan awalantest:
untuk menandakan bahwa ini commit untuk test.Selanjutnya lakukan perintah Git untuk kode solusi:
Perhatikan bahwa kini kita menambahkan file untuk solusi, yaitu
main.py
. Kita tuliskan pesan commit dengan awalanfeat:
untuk menandakan pembuatan fitur baru.Demikian panduan penerapan Test Driven Development (TDD) dengan Git. Semoga bermanfaat. Source code untuk praktik di atas terdapat pada link berikut
Rujukan
Beck, K. (2003). Test-driven Development: By Example. Addison-Wesley Professional.
Martin, R. C. (2005, October 6). The Three Rules Of Tdd. http://butunclebob.com.