PHPUnit, Pengecekan Coding yang Lebih Pro
September 19th, 2010, Written by: | Categories: Programming

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.

Unit Testing

Mengecek aplikasi tanpa Unit Testing

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 :

  1. desain kelas/fungsi
  2. buat sebuah rangkaian nilai yang ingin dites
  3. implementasi kelas/fungsi
  4. jalankan rangkaian test
  5. 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?

More about: , ,

6 Responses to “PHPUnit, Pengecekan Coding yang Lebih Pro”

  1. Fazlur Rahman

    Ternyata PHPUnit sudah dikenal sejak 2010..
    Thanks for this explanation :D

    Reply
  2. davidd

    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.

    Reply

Leave a Reply