Dreaming of things

17Dec/082

Unit Testing – Bagian I: Apa, mengapa?

Saat itu hujan rintik-rintik, halah seorang Interviewer bertanya pada saya, "Kamu tau Unit Testing?". Karena saya tidak ingin terlihat tidak tau sama sekali (padahal faktanya memang begitu), saya menjawab dengan sebuah pertanyaan, "Ngetes fungsional setiap bagian atau fitur dari aplikasi kan, Pak?". Beliau balik bertanya lagi, "Maksudmu, misalnya tes fungsional sebuah tombol dalam form dengan interaksi User?". Dengan percaya diri saya jawab "Iya, Pak. Setiap bagian fitur diuji oleh developer lalu diuji lagi pada saat UAT". "Oh bukan, bukan itu" kata beliau. Berhubung udah terlanjur (pengen) malu, saya balik tanya lagi "Trus, yang gimana dong, Pak?". Akhirnya beliau menjelaskan dalam beberapa kalimat singkat, apa itu Unit Testing ;D Semenjak saat itu, saya mulai mengimplementasikan unit testing pada proses software development sambil belajar sedikit demi sedikit.

Sebagian Software Engineer (maaf, saya lebih suka menggunakan istilah "Software Engineer" ketimbang "Developer" atau "Programmer" :) ) paham dengan baik apa itu Unit Testing, apa manfaatnya, dan bagaimana implementasinya. Sementara, sebagian yang lain tidak tau sama sekali dan bahkan baru pernah mendengar (yang terakhir ini mungkin cuma terjadi pada saya saat drama Interview yang saya ceritakan di atas ;P ).

Jadi...
Apa itu Unit Testing?

Unit Testing adalah salah satu bagian dari proses construction, di mana unit terkecil dari source code sebuah Software yang sedang dikembangkan, diisolasi secara terpisah antara satu dan lainnya, lalu diuji apakah output dari unit tersebut sudah sesuai dengan ekspektasi atau kebutuhan yang ada. Ekspektasi seperti apa yang dimaksud? Ekspektasi yang dihasilkan dari proses design (Pada Test Driven Development yang lebih ngetop dengan singkatan TDD, pembuatan Unit Testing merupakan proses design behavior unit itu sendiri), yaitu behavior yang diharapkan dari unit tersebut. Jika input nya begini maka seharusnya execution path (baris-baris code yang dieksekusi atau percabangan di dalam code) nya melalui baris ini lalu itu, hingga pada akhirnya menghasilkan sebuah target output tertentu. Inilah ekspektasi yang dimaksud. Muncul pertanyaan selanjutnya; Apakah yang dimaksud dengan unit terkecil? Dalam Procedural Programming, unit terkecil yang dimaksud adalah procedure. Dan dalam Object Oriented Programming, unit terkecilnya adalah sebuah method.

Ya, setiap method yang ada pada source code, masing-masing akan diuji secara terpisah. Sekalipun terjadi pemanggilan method A yang dipanggil oleh method B, method A harus tetap diuji dengan test scenario tersendiri yang memang dikhususkan untuk menguji method A. Walaupun, cukup dengan menguji method B, sebenarnya method A pun akan ikut teruji. "Ah, pemborosan, 'cost' nya kan jadi lebih besar, buat apa menguji method A, kalo cukup dengan menguji method B maka method A pun sudah ikut teruji?". Filosofi dari Unit Testing itu sendiri adalah mengisolasi dan menguji setiap unit secara parsial sebelum pada akhirnya nanti unit-unit tersebut akan memasuki pengujian lebih lanjut pada Integration Testing. Dan bayangkan satu hal, ketika seandainya suatu saat, method B ini behaviornya diubah dan tidak lagi memanggil method A. Kalo ini sampai terjadi dan method A sudah terlanjur tidak diuji secara tersendiri, apa jadinya? Sangat penting untuk diingat bahwa konsep Unit Testing adalah melakukan pengujian terhadap setiap unit secara tersendiri sesuai dengan test scenario masing-masing.

Pada implementasinya nanti, setiap execution path dapat diuji. Jelas bahwasannya pendekatan yang digunakan adalah white box, di mana si Tester (Software Engineer) dapat mengetahui detail implementasi obyek yang diujinya. Sebagai konsekuensinya, dalam implementasi Unit Testing, si Tester harus memiliki skill tertentu sesuai dengan behavior obyek (dalam hal ini adalah unit/method) yang diuji. Singkatnya, si Tester harus memiliki sufficient knowledege tentang bagaimana method yang diujinya bekerja. Baik development dengan metode biasa (non-TDD), terlebih lagi dengan metode TDD, di mana proses Unit Testing merupakan proses awal yang akan melahirkan sebuah unit atau method.

Test Harness

Sekarang ini sudah terdapat cukup banyak framework yang memfasilitasi Unit Testing secara otomatis. Framework-framework tersebut memiliki fitur untuk melakukan pengujian terhadap suatu method dengan memberikan input berupa parameter-parameter terhadap method tersebut, dan membandingkan output-nya dengan nilai yang kita inginkan. Framework seperti ini disebut dengan Test Harness, yang juga dapat menyediakan fasilitas untuk menganalisa hasil Unit Testing yang dijalankan. Saya akan membahas implementasi Unit Testing dengan menggunakan Framework yang dimiliki oleh .NET, yang telah dibungkus dengan cantik pada namespace Microsoft.VisualStudio.TestTools.UnitTesting. Tapi nanti, di artikel lain yang bakal berjudul "Unit Testing - Bagian II: Bagaimana?".

TDD

Pada Extreme Programming, Unit Testing digunakan untuk mendefinisikan behavior sebuah method. Teknik development ini disebut dengan Test Driven Development (TDD). Jika kita sudah terbiasa dengan urutan proses design class, kemudian mengembangkannya dengan coding, lalu melakukan testing terhadap source code tersebut, maka pada TDD alur yang terjadi dimulai dari testing (lebih tepatnya Unit Testing). Seorang Software Engineer akan membuat Unit Testing (bahkan) sebelum unit atau method yang akan di-test ada. Jangankan method, class pemilik method tersebut pun belum ada sama sekali. Tertarik untuk lebih mengetahui tentang TDD? Semoga saya bisa membahasnya pada artikel yang lain; "Unit Testing - Bagian IV: Test Driven Development".

Mengapa Unit Testing?

Biasanya pertanyaan "mengapa" erat kaitannya dengan tujuan atau alasan. Code Coverage! Code Coverage merupakan interpretasi dari tujuan Unit Testing; Untuk mengetahui apakah behavior unit yang kita buat sudah berjalan dengan baik dan sesuai dengan kebutuhan. Code Coverage akan menampilkan secara akurat presentase baris-baris yang tereksekusi (covered blocks) dan baris-baris yang tidak tereksekusi (not covered blocks) oleh sebuah Unit Testing. Code Coverage dapat menampilkan covered dan not covered blocks selama Unit Testing dalam bentuk visualisasi yang cukup interaktif (highlighting).

Code Coverage dan nilainya

Secara teori, nilai covered blocks dari Code Coverage yang sempurna adalah 100%. Artinya, seluruh execution path pada method yang diuji tereksekusi semua. Dengan begitu, dapat diasumsikan bahwa behavior method tersebut sudah sesuai dengan ekspektasi dan kebutuhan yang ada. Ketika covered blocks tidak mencapai angka 100% (ada not covered blocks berapapun prosentasenya), itu bisa berarti tiga hal. Yang pertama, mungkin ada Test Case atau Test Method tertentu yang belum dibuat untuk bisa melewati baris-baris not covered blocks tersebut. Yang kedua, bisa jadi semua Test Case sudah benar dan cukup. Hal ini mengindikasikan terdapat baris-baris yang seharusnya tidak perlu ada di dalam method yang kita buat. Dan baris-baris tersebut tidak lain adalah baris-baris not covered blocks tersebut. Kemungkinan yang terakhir adalah baris-baris not covered blocks tersebut memang sulit atau bahkan tidak bisa sama sekali untuk dilalui oleh Unit Testing (Unit Testing tidak bisa mereplikasi behavior baris-baris tersebut).

Muncul berbagai pendapat mengenai minimum Code Coverage (prosentase covered blocks). Ada yang berpendapat 75%, 80%, 85%, dan seterusnya dengan alasan masing-masing. Ada pendapat yang cukup anti Code Coverage dengan mengatakan tidak perlu memperhatikan berapa nilai Code Coverage, lebih penting untuk membuat Unit Testing yang fokus pada variasi pengujian input hingga batasan-batasan input tersebut. Kalo boleh, sebagai seorang cupu, dengan sedikit pengalaman dan pengetahuan saya pada Unit Testing, saya juga ingin berpendapat ;D Menurut saya, fokus pada variasi pengujian merupakan bentuk implementasi pengujian behavior unit itu sendiri. Jika ternyata setelah Code Coverage mencapai angka 100% masih ada Test Case yang failed, itu artinya behavior method atau unit yang diuji belum memenuhi ekspektasi atau kebutuhan yang seharusnya. Dan sebaliknya, ketika semua variasi Test Case yang dibutuhkan telah teruji dengan baik tapi Code Coverage tidak mencapai 100%, itu artinya ada baris-baris yang tidak perlu pada method kita. Masih dari pendapat saya juga, Tidak perlu ada minimum Code Coverage. Usahakan dengan sangat untuk selalu mencapai Code Coverage 100%. Ketika memang tidak memungkinkan untuk mencapai 100%, usahakan dengan sangat untuk mencapai angka Code Coverage semaksimal mungkin, berapapun itu. Memperhatikan Code Coverage sama pentingnya dengan variasi pengujian yang kita buat. IEEE sendiri merekomendasikan Code Coverage 100%.

Sedia payung sebelum hujan

Sementara Code Coverage adalah sebuah keuntungan yang bisa dirasakan secara langsung, maka ada keuntungan lain yang mungkin tidak dirasakan secara instan atau tidak kita sadari, tapi akan terasa dalam proses development cycle secara keseluruhan yaitu; Unit Testing bisa mendeteksi masalah lebih awal di dalam sebuah development cycle. Error yang ditemukan oleh Quality Assurance merupakan error yang memiliki cost yang besar untuk diperbaiki. Karena pada titik ini, secara keseluruhan system sudah terintegrasi di mana fungsional dari unit tidak hanya mempengaruhi dirinya sendiri tapi juga membentuk behavior system secara keseluruhan, sudah terjadi interaksi antara unit satu dan lainnya di dalam system. Itulah keuntungan dari Unit Testing selain Code Coverage; Mendeteksi masalah lebih dini ketika sebuah unit dibuat.

We're there

Pada akhirnya, manfaat Unit Testing ini akan mengerucut pada satu hal; Code Quality. Banyak metode best practice yang harus ditempuh dan diperhatikan untuk menghasilkan Code yang berkualitas, salah satunya dengan Unit Testing. Untuk teman-teman yang belum terbiasa dengan metode best practice, bisa segera memulai dari sekarang, mulai mempelajari Software Engineering dengan metode best practice. Terutama teman-teman mahasiswa yang belum banyak mencicipi bagaimana ganasnya dunia praktis itu sesungguhnya.

Baiklah, sampai jumpa di episode Unit Testing selanjutnya : )

Comments (2) Trackbacks (1)
  1. Wah, panjang juga artikelnya. Makasih, kebetulan saya baru belajar soal unit testing :-D

  2. belum sempet update lagi hehe.. happy unit testing ya :)


Leave a comment