Monday, February 21, 2005

Java: Tutorial menggunakan testing framework dengan JUnit

JUnit: Pengalaman pertama

Hari ini saya mencoba menggunakan JUnit test, unit testing framework untuk Java. Awalnya dari extreme programming, saya tau mengapa unit test begitu penting. Jadi sudah tau JUnit sudah lama tapi tidak pernah sampai mencoba menggunakannya karena merasa tidak ada waktu dan tidak dibutuhkan, selain itu proyek-proyek yang salakuakan biasanya memiliki time frame yang ketat artinya bukan sekedar waktu yang sangat sempit bahakan bisa dibilang sebenarnya proyek tidak bisa selesai dengan jangka waktu yang ditetapkan. Jadi prosedur testing sering kali dilakukan berbarengan dengan waktu development atau tidak ada fase testing yang cukup sehingga kualitas produknya rendah dan sering terjadi kesalahan pada saat sistem/program telah masuk masa production. Saya kira ini sering terjadi di proyek IT di Indonesia, yang tingkat korupsinya masih tinggi dan pengharaan waktunya kurang.

Pengalaman pertama yang memaksa saya melakukan unit testing adalah, database development saya ngaco (tidak bisa digunakan) ketika saya sedang melakukan bug fixing. Setelah bug di-fix, tentu saja saya tidak bisa melakukan testing di mesin production maka saya melakukan simulasi (tes) dengan menggunakan JUnit dan beberapa mock object sehingga testing bisa dilakukan tanpa perlu koneksi ke database. Sekarang saya akan menjelaskan sedikit tentang bagaimana menggunakan Junit untuk unit tes, tentu saja ini hanya sebuah artikel contoh penggunaan yang tidak menyeluruh.

Pertama download Junit framework di JUnit.org, kemudian simpan jar file di CLASSPATH

Kemudian mualailah coding class untuk testing. Class untuk testing tersebut akan memiliki format seperti ini:

import junit.framework.TestCase;

public class NamaClass_Test extends TestCase {
public NamaClass_Test(String name) {
super(name);
}

public void testSesuatu() {
// assert disini
}

public void testSesuatuLagi() {
// assert disana
}

public void testSesuatuLainnya() {
// assert dimana-mana
}
}

Unit class test yang kita buat harus merupakan child dari class junit.framework.TestCase, didalam unit class test tersebut kita dapat meng-override method setUp() untuk meletakan inisialisai varibel atau proses tertentu, dan meng-override method tearDown() untuk menyimpan bagian-bagian yang harus dieksekusi setelah test dalam class tersebut selesai, misalnya menutup koneksi ke database.

Jangan gunakan constructor untuk menginisialisasikan sesuatu yang akan ditest, gunakanlah setUp(), karena jika terjadi error akan menghasilkan error message yang tidak informatif yaitu unit.framework.AssertionFailedError: Cannot instantiate test case ...

Selain itu kita dapat membuat method-method public tanpa return value (void) dengan awalan test untuk meletakan kode testing kita.
Didalam method test yang kita buat, kita melakukan assertions (kamus: to state or express positively) yaitu membandingkan hasil aktual dengan hasil yang diharapkan (expected).

assertEquals(...)
assertTrue
(...)
assertFalse(...)
assertNull(...)
assertNotNull(...)
assertSame(...)
assertNotSame(...)
fail(...)

Lihat dokumentasi untuk lebih jelasnya mengenai method-method diatas. Method assert diatas pada umumnya memiliki argumen (expected_result, actual_result) atau (Pesan_Kesalahan, expected_result, actual_result). Jika hasil expected_result sama actual_result maka JUnit akan mengganggap test sukses.
perhatikan method dengan assertion berikut ini:

public void testSesuatu() {
SomethingVO someVO = (new BusinessClass()).transferToManager(99);
assertEquals(
"SomethingVO tidak bisa ditransfer",
new SomethingVO("Something No 99"),
someVO);
}

Pada contoh diatas JUnit akan mengecek apakah result object someVO sama dengan expected object SomethingVO("Something No 99"), jika sama maka kita dapat mengatakan method transferToManager lulus tes.

Dengan menggunakan banyak method berawalan test dalam satu class, kita megumpulakan satu fungsional test dalam satu class dan kita akan dapat dengan mudah meng-execute semua method-method tersebut dengan cara membuat method main seperti ini:

public static void main(String[] args) {
TestRunner.run(NamaClass_Test.class);
}

Contoh output jika class tersebut di-execute adalah :

There were 2 failures:
1) testSesuatu(com.test.NamaClass_Test)junit.framework.AssertionFailedError: Sesuatu is NOT accepted
at com.test.CaseWorklistTest.testTransferToCollector(NamaClass_Test.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.test.NamaClass_Test.main(NamaClass_Test.java:174)
2) testSesuatuLagi(com.test.NamaClass_Testjunit.framework.AssertionFailedError: Sesuatu is already assign
at com.test.NamaClass_Test.testAssign(NamaClass_Test.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.test.NamaClass_Test.main(NamaClass_Test.java:174)

FAILURES!!!
Tests run: 3, Failures: 2, Errors: 0

Nah, kita bisa lihat ada 3 tes yang telah run, ada 2 assertion failure dan 0 error.

JUnit memberikan beberapa cara yang dapat dilakukan untuk mengeksekusi class TestCase, kita bisa membuat main method seperti diatas atau bisa menggunakan GUI tool

java -classpath D:\junit3.8.1\junit.jar junit.swingui.TestRunner NamaClass_Test

Kita dapat mengelompokan beberapa TestCase menjadi satu group/suite dengan menggunakan class TestSuite. Dengan TestSuite, kita dapat menjalankan banyak TestCase sekaligus dan bahkan menggabungkan atau menjalankan beberapa TestSuit sekaligus.

public class SuitSuiw_Test() {
public static Test suite ( ) {
TestSuite suite = new TestSuite();

// Tambahakan dua buah TestCase bernama NamaClass0_Test dan NamaClass1_Test
// dan sebuah TestSuit bernama NamaClass2_Test
suite.addTest(new NamaClass0_Test("testMoneyEquals"));
suite.addTest(new NamaClass1_Test("testSimpleAdd"));
suite.addTest(new NamaClass2_Test().suite());
}
}

Kemudian buatlah main method untuk eksekusi

public static void main (String[] args) {
junit.textui.TestRunner.run( suite() );

// Gunakan statement dibawah ini untuk hasil dengan GUI
//junit.swingui.TestRunner.run( suite() );
}

Selesai..

No comments:

Followers