Wednesday, February 22, 2006

Testing with Hansel

Hansel คือ code coverage ตัวหนึ่ง
จุดที่ผมชอบ ก็คือ วิธีที่มัน integrate กับ JUnit ซึ่งดูเรียบง่ายดี

ลองดูตัวอย่าง
ทดลองเขียน Collection ขึ้นมาอันหนึ่ง ที่เก็บ integer
โดย item ใน collection จะเรียงลำดับจากน้อยไปมากเสมอ
public class OrderList {

private ArrayList bag;

public OrderList() {
bag = new ArrayList();
}

public void add(int value) {
int size = bag.size();
boolean found = false;
for (int i = 0; i < size; i++) {
Integer elm = (Integer) bag.get(i);
if (value < elm.intValue()) {
if (i == size -1) {
bag.add(new Integer(value));
} else {
bag.add(i, new Integer(value));
}
found = true;
break;
}
}
if (! found) {
bag.add(new Integer(value));
}
}

public int first() {
return ((Integer) bag.get(0)).intValue();
}

public int last() {
return ((Integer) bag.get(bag.size() - 1)).intValue();
}
}


เขียน JUnit Testcase
public class TestOrderList extends TestCase {

/*
* Test method for 'util.OrderList.first()'
*/

public void testFirst() {
OrderList l = new OrderList();
l.add(6);
l.add(9);
l.add(1);
assertEquals(1, l.first());

}

/*
* Test method for 'util.OrderList.last()'
*/

public void testLast() {
OrderList l = new OrderList();
l.add(6);
l.add(9);
l.add(1);
assertEquals(9, l.last());

}

}


ทดลอง run ดู ก็จะพบแถบเขียวสวยงาม



ที่นี้ลองใส่ Hansel เข้าไป
โดยการเพิ่ม method นี้ลงไปใน test case
    public static Test suite() {
return new CoverageDecorator(TestOrderList.class,
new Class[] {OrderList.class});
}


ทดลอง run ใหม่



จะเห็น message error ว่า
 Coverage failure: Branch not completely covered. Condition 'i == size - 1' is not fulfilled.
at util.OrderList.add(OrderList.java:20)


ไปไล่โปรแกรมแล้ว จะพบที่ผิดตัวเบ้อเริ่มเลย
บรรทัดที่ 20 เป็นบรรทัดที่ตกค้างจากการที่เขียน code โดยไม่ได้วางแผนมาก่อน
สามารถตัดทิ้งออกไปได้ทั้งยวงเลย

จะเห็นว่า Hansel เข้ามาช่วยอุดจุดอ่อน
ของ Programer ที่ไม่ชอบวางแผน ชอบเขียนโปรแกรมไป-คิดไป-แก้ไป
(แก้ไปแก้มา จนงงเอง) ได้เป็นอย่างดี

หลักการทำงานของ Hansel ก็คือ มันจะทำการ modify class file ที่เราต้องการ test
โดยใช้ BCEL (Byte Code Engineering Library)
ทำการใส่ probe เข้าไปตามบรรทัดต่างๆ แล้ว check ดูว่ามีการเรียกใช้ probe เหล่านั้นหรือไม่
การใส่ probe ของ Hansel ก็ไม่ได้ใส่ดะไปทุก statement นะ
มีการเลือกใส่เฉพาะ statement ที่เป็น branch เท่านั้น

Related link from Roti

No comments: