Semakin cepat ditemukan kesalahan, maka semakin besar kemungkinan untuk memperbaikinya dengan cost yang sedikit. Itu sebabnya mengapa melakukan testing ketika software/website siap untuk dirilis sungguh merupakan sebuah hal yang bermasalah.
Umumnya sebagai programmer PHP,kita mencoba input-input form dengan nilai-nilai tertentu. Kemudian misalnya ternyata hasilnya tidak sesuai maka menggunakan echo
, print_r
atau mungkin var_dump
dan didampingi fungsi die()
untuk mencari kesalahan. Tetapi ada juga programmer yang levelnya lebih tinggi dari programer biasa. Mereka akan menulis beberapa baris coding dan kemudian menjalankan skrip kode untuk kelas/fungsi tertentu tersebut untuk melihat hasilnya sesuai harapan atau tidak. Itulah unit test. Pengetesan pada class atau fungsi API.
Kali ini kami akan memperkenalkan salah satu framework untuk testing unit di PHP yakni PHPUnit. Framework ini diciptakan oleh Sebastian Bergmann, seorang pioner di bidang quality assurance dalam projek PHP.
Alur pekerjaan programer pada umumnya adalah membuat terlebih dahulu class, kemudian testing, setelah itu baru digunakan. Dengan PHPUnit maka akan sedikit berbeda alurnya. Berikut merupakan kira-kira alur yang cukup baik untuk menjelaskan dari pear.php.net :
- desain kelas/fungsi
- buat sebuah rangkaian nilai yang ingin dites
- implementasi kelas/fungsi
- jalankan rangkaian test
- perbaiki kesalahan atau error dan kembali ke langkah ke 4
Langkah-langkah ini mungkin kelihatannya memerlukan waktu yang sangat banyak, tetapi sebenarnya tidaklah demikian. Faktanya untuk membuat sebuah rangkaian test dengan PHPUnit cukup beberapa menit dan untuk menjalankan test cukup beberapa detik.
Untuk memberi gambaran sekilas bagaimana menggunakan PHPUnit maka kami akan menyajikan contoh-contoh coding dari website pear.php.net.
Pertama, kita akan membuat kelas terlebih dahulu. Untuk contoh kali ini kita akan membuat sebuah kelas String.
Setelah selesai membuat kelas, sekarang langkah berikutnya kita membuat rangkaian tes. Tes ini akan mengecek semua fungsi di kelas String tadi. Dalam fungsi tes nilai yang diharapkan akan dibandingkan dengan hasil dari fungsi. Hasil dari komparasi(membandingkan) nilai ini dilakukan oleh fungsi assert*() yang disediakan PHPUnit. Fungsi itu akan menentukan apakah lulus atau gagal melewati tes.
<?php //---- testcase.php ---- require_once 'string.php'; require_once 'PHPUnit.php'; class StringTest extends PHPUnit_TestCase { // contains the object handle of the string class var $abc; // constructor of the test suite function StringTest($name) { $this->PHPUnit_TestCase($name); } // called before the test functions will be executed // this function is defined in PHPUnit_TestCase and overwritten // here function setUp() { // create a new instance of String with the // string 'abc' $this->abc = new String("abc"); } // called after the test functions are executed // this function is defined in PHPUnit_TestCase and overwritten // here function tearDown() { // delete your instance unset($this->abc); } // test the toString function function testToString() { $result = $this->abc->toString('contains %s'); $expected = 'contains abc'; $this->assertTrue($result == $expected); } // test the copy function function testCopy() { $abc2 = $this->abc->copy(); $this->assertEquals($abc2, $this->abc); } // test the add function function testAdd() { $abc2 = new String('123'); $this->abc->add($abc2); $result = $this->abc->toString("%s"); $expected = "abc123"; $this->assertTrue($result == $expected); } } ?>
Kita sudah membuat rangkaian tes, maka langkah selanjutnya adalah mengetes rangkaian tes itu sendiri dengan mengirim nilai kosong. Kita harus yakin bahwa rangkaian tes ini harus fail(gagal) semuanya. Mengapa? Karena kita sedang mengetes sesuatu yang masih kosong. Jadi apabila ternyata rangkaian testnya malah ada yang pass di tahap ini(padahal sudah jelas-jelas datanya kosong) tentu ada masalah di koding rangkaian test yang dibuat tadi.
Berikut merupakan jalur untuk menjalankannya
<?php //---- stringtest.php ---- require_once 'testcase.php'; require_once 'PHPUnit.php'; $suite = new PHPUnit_TestSuite("StringTest"); $result = PHPUnit::run($suite); echo $result->toString(); ?>
Jika anda memanggil skrip dari commandline, anda akan mendapatkan output berikut:
TestCase stringtest->testtostring() failed: expected true, actual false
TestCase stringtest->testcopy() failed: expected , actual Object
TestCase stringtest->testadd() failed: expected true, actual false
Setelah selesai mencoba rangkaian tes, maka saatnya untuk implementasi kelas String.
<?php //---- string.php ---- class String { //contains the internal data var $data; // constructor function String($data) { // $this->data = $data; // } // creates a deep copy of the string object function copy() { $ret = new String($this->data); return $ret; } // adds another string object to this class function add($string) { $this->data = $this->data.$string->toString("%ss"); } // returns the formated string function toString($format) { $ret = sprintf($format, $this->data); return $ret; } } ?>
Ketika implementasi selesai dan kita mencoba menjalankannya dengan commandline:
php -f stringtest.php
TestCase stringtest->testtostring() passed
TestCase stringtest->testcopy() passed
TestCase stringtest->testadd() failed: expected true, actual false
Ternyata hasilnya ada false. Setelah dicek-cek ternyata fungsi add() di kelas salah tulis. Kita perbaiki tulisan ini menjadi
data = $this->data.$string->toString("%s"); ?>
Tes sekali lagi dan coba dijalankan lagi:
php -f stringtest.php
TestCase stringtest->testtostring() passed
TestCase stringtest->testcopy() passed
TestCase stringtest->testadd() passed
Okay, semuanya berjalan dengan benar.
Sekilas dilihat sepertinya banyak sekali yang harus dilakukan hanya untuk mengetes tiga fungsi sederhana. Anda pasti merasa “sepertinya lebih cepat pakai cara echo dan die() deh”. Okay, memang untuk coding sederhana ini terlihat mubazir, tetapi coba pikirkan ketika kita harus mengembangkan aplikasi yang kompleks seperti aplikasi shopping cart, di mana kita mungkin harus membuat kelas Basket atau kelas Checkout yang rumit. Untuk kasus seperti demikian maka PHPUnit benar-benar sangat berguna untuk mendeteksi error secara dini.
Contoh kegunaan lainnya adalah, bisa saja anda terkadang perlu mengimplementasikan kelas yang sudah dibuat ke projek atau aplikasi lain. Tanpa adanya rangkaian tes, kemungkinan untuk merusak sesuatu dalam aplikasi yang tergantung pada kelas tersebut sangat besar, misalnya karena kita menambah-nambah fitur, tanpa sengaja mengubah koding lama kelas. Di sinilah letak kekuatan unit test. Anda akan menciptakan sebuah rangkaian tes, dan mengembangkan kelas kamu, selama dia lulus tes, maka anda dapat yakin bahwa aplikasi yang bergantung pada kelas tersebut pasti berjalan.
Mungkin sudah saatnya berpikir-pikir beralih ke teknik pengecekan yang lebih profesional?
[...] This post was mentioned on Twitter by Garry Bernardy, Computesta. Computesta said: New blog post: PHPUnit, Pengecekan Coding yang Lebih Pro http://bit.ly/cqmor2 [...]
Ternyata PHPUnit sudah dikenal sejak 2010..
Thanks for this explanation
Terima kasih atas sharenya, sangat bermanfaat ..
Makasih sharingnya ya…bookmark dulu ya
Terima Kasih bro. Bermanfaat banget
trims atas infonya. mau tanya nih, kebetulan masih pemula,
mana yg bagus ngetesnya pakai phpunit atau xdebug?
saya sekarang sedang mencoba pakai netbeans yg bisa pakai xdebug. sejauh ini bagus.
tapi sekarang baru tahu lagi tentang phpunit ini, jadi mau tanya-tanya dulu barangkali agan udah mencoba keduanya, yg mana yg paling mudah menurut pengalaman agan. itu saja. mohon jawabannya ya, please.