suhe arie's pages

Programmer juga manusia

Towards bug-free software – Unit Testing dengan JUnit 4

Unit testing menjadi semakin populer beberapa tahun belakangan ini, seiring dengan permintaan akan peningkatan kualitas software yang mendekati sempurna. Meskipun sebuah aplikasi yang 100% ‘bug free’ tidak akan pernah ada, tetapi setidaknya ada beberapa hal yang bisa dilakukan untuk menuju ke arah tersebut. Salah satunya adalah dengan mengimplementasikan unit testing.

Secara sederhana, unit testing dapat diartikan sebagai pengujian/testing terhadap satuan terkecil atau komponen dari sebuah software atau aplikasi untuk memastikan bahwa komponen tersebut bekerja dengan baik, sebelum melakukan testing terhadap aplikasi secara keseluruhan. Metode ini sebenarnya bukan hal yang sama sekali baru. Banyak orang sudah melakukan hal ini sejak lama dengan cara manual. Setelah komponen selesai di-develop, programmer atau tester akan melakukan test secara manual terhadap komponen tersebut dengan memberikan berbagai macam input and menganalisa output yang diberikan oleh komponen tersebut. Hal ini tentunya membutuhkan waktu yang panjang dan bisa jadi merupakan sesuatu yang membosankan, karena harus dilakukan berulang-ulang sampai semua skenario selesai diuji dan memberikan hasil sesuai ekspektasi. Inilah yang akhirnya memunculkan ide untuk membangun framework untuk melakukan unit testing secara otomatis (automated unit testing). Metode ini mengarah pada sesuatu yang dinamakan Test Driven Development, dimana skenario test didefinisikan terlebih dahulu, bahkan sebelum aplikasinya sendiri mulai didevelop.

Dengan unit test otomatis, semua skenario test bisa dijalankan secara otomatis, berulang-ulang, tanpa melibatkan interaksi manusia. Unit test penting untuk dilakukan secara terus menerus, berulang-ulang – setiap kali kode aplikasi mengalami perubahan – untuk memastikan bahwa setiap komponen masih berfungsi dengan benar setelah adanya penambahan fitur atau perbaikan logika di dalam komponen tersebut. Dengan demikian, tester bisa mengalihkan fokus pada testing terhadap aplikasi secara keseluruhan. JUnit (http://www.junit.org/) adalah framework unit test yang populer untuk aplikasi yang dibangun dengan Java. Untuk melakukan unit test, programmer perlu menulis kode tambahan (selain kode aplikasi itu sendiri) yang memberikan berbagai macam input dan mengindikasikan output yang diharapkan. Hal ini biasanya dilakukan terhadap setiap method dari setiap class, yang bisa dianggap sebagai unit terkecil dari aplikasi. Release terakhir dari JUnit adalah JUnit 4 yang mengimplementasikan annotation untuk mempermudah programmer untuk menuliskan test class.

OK, let’s get started..

Misalkan saya punya sebuah class yang sederhana untuk melakukan kalkulasi:

public class DummyCalculator {

	public int plus(int a, int b) {
		return a+b;
	}

	public int minus(int a, int b) {
		return a-b;
	}

	public int divide(int a, int b) {
		return a/b;
	}

}

Sekarang, saya akan membuat unit test untuk memastikan bahwa method ‘plus’ dan ‘minus’ selalu menghasilkan output yang benar. Untuk itu, saya menuliskan class untuk unit testnya sebagai berikut:

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestDummyCalculator {

	DummyCalculator instance = null;

	@Before
	public void setUp() throws Exception {
		System.out.println("Setting up before test");
		instance = new DummyCalculator();
	}

	@After
	public void tearDown() throws Exception {
		System.out.println("Cleanup after test");
	}

	@Test
	public void testPlus() {
		System.out.println("Start test: plus method");
		assertEquals(2, instance.plus(1, 1));
		assertEquals(0, instance.plus(-1, 1));
		System.out.println("Test finished: plus method");
	}

	@Test
	public void testMinus() {
		System.out.println("Start test: minus method");
		assertEquals(0, instance.minus(1, 1));
		assertEquals(-2, instance.minus(-1, 1));
		System.out.println("Test finished: minus method");
	}

	@Test
	public void testDivide() {
		System.out.println("Start test: divide method");
		assertEquals(1, instance.divide(1, 1));
		assertEquals(3, instance.divide(6, 2));
		System.out.println("Test finished: divide method");
	}
}

Secara sederhana, JUnit memberi kita kesempatan untuk melakukan initialisasi, melakukan test, dan melakukan pembersihan (clean-up). Hal-hal tersebut di atas diimplementasikan melalui method-method yang diberi annotation khusus:

  • @Before: method untuk initisalisasi
  • @Test: method untuk melakukan test
  • @After: method untuk clean-up

Anda bisa menggunakan nama method apa saja, asalkan diberi annotation dengan benar. Satu class bisa memiliki banyak method untuk melakukan test (diberi annotation @Test). Di JUnit 4, class untuk unit test juga tidak harus meng-extend TestCase class. Method testPlus, testMinus, dan testDivide adalah method-method yang melakukan unit test. Di dalam method-method ini saya memanggil method yang ada di class DummyCalculator dengan memberi beberapa macam input dan assertEquals adalah method yang disediakan oleh JUnit untuk membandingkan output yang kita harapkan dan output aktual yang dihasilkan oleh DummyCalculator class. Ada banyak method lain yang disediakan oleh JUnit untuk melakukan hal serupa (assertTrue, assertNotNull, dll).

Eksekusi unit testing bisa dilakukan melalui command line, build tool (seperti ANT), atau dari IDE (seperti Eclipse). Di contoh ini, saya akan mengeksekusi unit test melalui  Eclipse karena Eclipse sudah menyediakan plugin untuk JUnit4 yang bisa menampilkan hasil unit test secara visual. Unit test dapat dilakukan dengan memilih menu Run -> Run As -> JUnit Test.

Hasilnya:

Jika ada test case yang tidak berhasil (error atau output tidak sesuai), Eclipse akan menunjukkan indicator berwarna merah dan menunjukkan test mana yang gagal.

Untuk Anda yang ingin mengetahui fitur JUnit yang lain, ada 2 fitur yang akan saya highlight. Yang pertama adalah method untuk melakukan initialisasi global (dengan annotation @BeforeClass) dan clean-up global (dengan annotation @AfterClass). Method-method ini akan dieksekusi hanya satu kali untuk keseluruhan test class, tidak seperti @Before dan @After yang dieksekusi untuk setiap test case.

	@BeforeClass
	public static void setUpGlobal() throws Exception {
		System.out.println("Setting up - global");
	}

	@AfterClass
	public static void tearDownGlobal() throws Exception {
		System.out.println("Cleanup  - global");
	}

Fitur yang lain adalah exception expectation, untuk melakukan test dimana kita mengharapkan bahwa eksekusi unit test akan menghasilkan exception tertentu.

	@Test(expected = ArithmeticException.class)
	public void testDivideWithException() {
		System.out.println("Start test: divide method with exception");
		assertEquals(1, instance.divide(1, 0));
		System.out.println("Test finished: divide method with exception");
	}

Selamat membangun bug-free software..

October 26, 2012 - Posted by | Java | , ,

1 Comment »

  1. nice Bro…..keep update 🙂

    Comment by iie | December 28, 2012 | Reply


Leave a reply to iie Cancel reply