Senin, 24 November 2008

Unit Testing di PHP (Bagian 1 Instalasi)

Sejalan dengan berkembangnya Object Oriented di PHP, penggunaan Testing Framework menjadi hal yang semakin banyak dibicarakan. Selain itu, PHP juga telah berkembang dari sekedar menambahkan efek dinamis di sebuah website kecil, menjadi bahasa pemrogramman aplikasi besar yang perlu memperhatikan ketepatan jalannya sebuah logika aplikasi. Dengan melakukan test yang menyeluruh, kita dapat memastikan ketepatan dari aplikasi yang kita bangun, seperti yang dijelaskan pada blog mengenai keuntungan melakukan test. Melihat hal tersebut, kita sebagai pembangun aplikasi di PHP harus sesegera mungkin mempelajari Testing Framework yang dapat membantu dalam pembangunan aplikasi.

Salah satu testing framework yang sering digunakan untuk melakukan Unit Testing di PHP adalah PHPunit. PHPunit merupakan bagian dari xUnit Testing Framework yang memudahkan penulisan testing dan menganalisa hasil dari test yang dilakukan. Instalasi PHPunit sendiri sangat mudah karena menggunakan bantuan PEAR installer dalam menjalankannya. Berikut cara instalasi PHPunit menggunakan PEAR installer.

Pertama-tama kita perlu mendaftarkan PEAR channel yang digunakan untuk mendistribusi PHPunit. Hal ini dilakukan dengan memberikan perintah:

pear channel-discover pear.phpunit.de

Setelah hal tersebut dijalankan, instalasi dapat dilakukan dengan:

pear install phpunit/PHPUnit


Setelah instalasi selesi, kita dapat menemukan file source PHPUnit di tempat kita meletakkan PEAR package. Hal ini tergantung distribusi PHP anda. Ada baiknya kita menambahkan directory tempat phpunit ke dalam PATH sehingga kita bisa memanggil program tersebut dari mana saja. Untuk memastikan instalasi berhasil, coba jalankan perintah berikut:

phpunit --version

akan keluar versi dari phpunit yang terinstall di tempat anda. Sekarang, kita tinggal membuat Unit Test yang sesuai dengan aplikasi yang kita bangun dan memanggil phpunit untuk menjalankannya. Bagaimana cara membuat unit test pertama anda, dengan menggunakan PHPUnit, akan dijelaskan pada tulisan berikutnya.

Jumat, 21 November 2008

Stress Test Aplikasi Web dengan Apache ab2

Salah satu tugas dari pembangun aplikasi adalah melakukan test terhadap aplikasi yang dibangunnya. Salah satu test yang perlu untuk dilakukan adalah Stress Test. Stress test aplikasi web bertujuan untuk melihat apakah aplikasi yang telah dibangun di atas sebuah web server dapat berjalan dengan stabil dengan beban yang diberikan. Dalam tersebut kita memberikan beban yang berbeda-beda kepada aplikasi dan melihat respon dari aplikasi web tersebut.

Untuk melakukan stress test aplikasi web tersedia berbagai macam tools. Salah satu yang menarik adalah Apache Ab (ab2 di Opensuse). Tools tersebut disediakan langsung oleh apache web server sebagai bagian dari system toolsnya. Penggunaannya sangat mudah dan tidak memerlukan banyak setting. Di Opensuse tools tersebut bisa didapatkan dengan menginstall paket apache2-utils. Untuk menggunakannya lakukan perintah berikut:

# ab -kc 10 -t 30 http://localhost/
Perintah di atas akan melakukan sepuluh koneksi secara bersamaan ke web server anda dan melakukan request secara terus menerus selama 30 detik. Hasil yang dilaporkan pun cukup menarik dan bisa diexport ke gnuplot format ataupun csv. Berikut contoh hasil dari perintah di atas:

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Finished 50000 requests


Server Software: Apache/2.2.4
Server Hostname: localhost
Server Port: 80

Document Path: /
Document Length: 163 bytes

Concurrency Level: 10
Time taken for tests: 8.804394 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 49509
Total transferred: 22530617 bytes
HTML transferred: 8150978 bytes
Requests per second: 5678.98 [#/sec] (mean)
Time per request: 1.761 [ms] (mean)
Time per request: 0.176 [ms] (mean, across all concurrent requests)
Transfer rate: 2498.98 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 4
Processing: 0 1 4.2 1 282
Waiting: 0 1 4.2 1 282
Total: 0 1 4.2 1 282

Percentage of the requests served within a certain time (ms)
50% 1
66% 1
75% 1
80% 1
90% 2
95% 2
98% 4
99% 5
100% 282 (longest request)


Untuk melihat performance dari aplikasi web kita, ganti nilai -kc (concurrent connetion) dengan angka yang terus bertambah (hingga 50 sebagai contoh) dan tingkatkan batas waktu (-t) sehingga test dapat dilakukan dalam jangka waktu yang cukup untuk diukur. Kemudian, bandingkan hasil antara jumlah conccurent connection yang berbeda-beda tersebut. Selamat mencoba

Static Keyword di PHP5

Dengan mendefinisikan sebuah property ataupun method menggunakan kata-kata static, kita dapat mengakses property atau method tersebut tanpa melakukan inisiasi terhadap class yang mendefinisikannya. Dari dokumentasi mengenai static keyword di PHP5, ada beberapa hal yang perlu diperhatikan:
1. Deklarasi kata static harus setelah deklarasi dari visibility, contoh

public static $data;

BUKAN

static public $data;

Jika tidak ada deklarasi visibility, maka property atau method tersebut akan dianggap public.

2. Karena static method dapat dipanggil tanpa melakukan instansiasi dari object, maka penggunaan kata '$this' tidak berlaku untuk method yang menggunakan deklarasi static.

3. Static property tidak dapat diakses menggunaan operator tanda panah (->), tetapi static method dapat diakses dengan operator tanda panah.

Sekarang kita melihat contoh dari property dan method yang bersifat static:

class MyClass {

public static $data = 5;
public $id;

public function setData($data) {
self::$data = $data;
}

public function getData() {
return self::$data;
}

public function setId($id) {
$this->id = $id;
}

public function getID() {
return $this->id;
}

public static function staticGetData() {
return self::$data;
}
}


Dengan class di atas, kode-kode di bawah ini dapat dilakukan:

echo MyClass::$data; // Mengeluarkan angka 5, tidak perlu melakukan intansiasi class
echo MyClass::staticGetData() // Mengeluarkan angka 5, tidak perlu melakukan intansiasi class

$x = new MyClass();
$x->setId(3);

echo $x->getId(); // Mengeluarkan angka 3, harus melakukan instansiasi sebelum dipanggil
echo $x->getData(); // Mengeluarkan angka 5, harus melakukan instansiasi sebelum dipanggil


Nah, sekarang beberapa contoh yang menarik untuk meningkatkan pemahaman terhadap pengaruh static deklarasi terhadap property di class:

$x = new MyClass();
$x->setId(3);
$x->setData(12);

// Print out nilai di X
echo 'Nilai id di $x: ' . $x->getId() . ' -- nilai data di $x: ' . $x->getData() . '<br/>';

$y = new MyClass();
$y->setId(8);
$y->setData(30);

// Print out nilai di Y
echo 'Nilai id di $y: ' . $y->getId() . ' -- nilai data di $y: ' . $y->getData() . '<br/>';

// Sekarang kita coba lagi dengan nilai di X
echo 'Nilai id di $x: ' . $x->getId() . ' -- nilai data di $x: ' . $x->getData() . '<br/>';


Perhatikan baik-baik nilai yang dihasilkan, terutama nilai X di pemanggilan kedua dibandingkan dengan nilai Y. Dengan deklarasi static, property $data di X dan di Y merupakan dua hal yang sama. Perubahan di satu tempat akan merubah hal yang lain. Lalu, apa bagusnya hal tersebut?

Beberapa hal yang dapat dilakukan dengan deklarasi static:
1. Melakukan Singleton Pattern dimana sepanjang proses hanya terdapat satu instance dari class yang kita inginkan.

2. Menggantikan $_GLOBAL variable. Karena kita bisa mengakses property static tersebut dari mana saja, kita bisa menggunakannya untuk menggantikan $_GLOBAL variable. Kelebihannya adalah kita mempunyai namespace karena property didefinisikan di dalam class. Artinya, kita bisa memiliki dua buah property static yang bernama $data di dua class yang berbeda dan tidak perlu khawatir saling bertabrakan. Contoh:

class NumberOne {
public static $data = 3;
}

class NumberTwo {
public static $data = 'test';
}

echo "Value number one: " . NumberOne::$data;
echo "Value number two: " . NumberTwo::$data;


Semoga dapat menambah pengetahuan.