Rabu, 03 Desember 2008

Unit Testing di PHP (Bagian 3 Test Exception)

Tulisan sebelumnya membahas mengenai cara membuat Unit Test pertama anda. Telah diterangkan mengenai struktur dasar dari class test dan juga melakukan pembuatan sebuah class secara bertahap. Masing-masing tahap ditujukan untuk melewati test yang telah dibuat. Sekarang kita akan melanjutkan untuk membuat unit test dengan PHPUnit yang melakukan test terhadap exception.

Kita akan melakukan percobaan terhadap method divide di class calculator kita. Pertama kita buat dulu method untuk testnya:

public function testDivide() {
$this->assertEquals(3, $this->calculator->divide(6, 2));
}

Jika kita jalankan test kita
> phpunit CalculatorTest

akan muncul error yang sangat panjang dan jika kita lihat lebih teliti akan terdapat kata-kata:
Fatal error: Call to undefined method Calculator::divide()
Tentunya ini terjadi karena kita belum membuat method divide di class calculator kita. Tambahkan bagian berikut di class Calculator:

public function divide($a, $b) {

}

Jika kita jalankan lagi, maka akan keluar:
Failed asserting that <null> matches expected value <integer:3>

Ah.. ternyata kita belum mengisi method divide kita. Kita isi method divide dengan potongan program berikut:

return $a/$b;

Jika kita coba lagi, maka test kita akan berhasil. Berikutnya, kita coba tambahkan dengan test yang lain, method testDivide kita menjadi seperti berikut:

public function testDivide() {
$this->assertEquals(3, $this->calculator->divide(6, 2));
$this->assertEquals(7, $this->calculator->divide(49, 7));
}
Jika kita jalankan test, ternyata hasilnya masih ok. Mari kita tambahkan untuk pembagian lainnya:

public function testDivide() {
$this->assertEquals(3, $this->calculator->divide(6, 2));
$this->assertEquals(7, $this->calculator->divide(49, 7));
$this->assertEquals(0, $this->calculator->divide(32, 0));
}

Ternyata terjadi error "Division by zero". Hal tersebut terjadi karena kita melakukan pembagian dengan angka 0. Bagaimana kita mengatasi error tersebut?

public function testDivide() {
$this->assertEquals(3, $this->calculator->divide(6, 2));
$this->assertEquals(7, $this->calculator->divide(49, 7));
try {
$this->calculator->divide(32, 0);
$this->fail('Expected exception does not occur');
} catch (Exception $e) {
$this->assertEquals('Division by zero', $e->getMessage());
}
}

Yang perlu diperhatikan dari program di atas adalah penggunaan try .. catch. Kita berusaha menangkap kesalahan yang terjadi di dalam program kita. Jika terjadi kesalahan, maka di dalam blok catch kita membandingkan apakah terdapat pesan 'Division by zero' dari kesalahan tersebut. Selain itu, setelah kita melakukan pemanggilan method divide dengan pembagi 0, terdapat pernyataan:

$this->fail('Expected exception does not occur');

Pernyataan tersebut menyebabkan test kita akan gagal jika TIDAK terjadi exception yang diharapkan. Dengan cara ini, kita memastikan bahwa exception yang kita inginkan harus terjadi di program calculator kita. Dan dengan try .. catch kita menghindari terjadinya error dari test yang dilakukan.