JUnit: เริ่มต้น

posted on 31 Aug 2008 01:29 by wonam in softdev

JUnit เป็น testing framework ที่พัฒนาโดย Kent Beck and Erich Gamma ถ้าถามโปรแกรมเมอร์ Java ว่าเคยทำ unit testing หรือเปล่า คิดว่าส่วนมากที่เคยน่าจะเคยใช้ JUnit รุ่นล่าสุดของ JUnit ตอนนี้คือ 4.5

(ในภาคการศึกษาหน้ามีสอนวิชา software testing ปกติเอกสารที่ใช้สอน (สไลด์) ก็มีตัวอย่างอะไรอยู่แล้ว แต่อาจจะเขียนอ่านยาก ไม่ลงรายละเอียด แถมเป็นภาษาอังกฤษ ก็เลยขอมาเขียนเอาไว้ในบล็อกด้วย หวังว่าจะไม่ได้เป็นการเอามะพร้าวห้าวมาขายสวนนะครับ ถ้าใครมีข้อเสนอแนะก็ฝากไว้ได้เลยครับ)

การทำ unit testing แปลตรง ๆ ก็คือการทดสอบระดับหน่วยของโปรแกรม ทีนี้อะไรบ้างที่จะเป็น unit? จริง ๆ แล้วในทางปฏิบัติเราก็ไม่ได้มีข้อจำกัดว่าอะไรบ้างต้องเป็น unit แต่ขอให้มีขนาดเล็กและมีหน้าที่ที่ชัดเจนเพียงอย่างเดียว

หลักการง่ายของการทดสอบ unit ก็คือการสร้างสภาพแวดล้อมตั้งต้นให้ได้ตามต้องการ จากนั้นเรียกใช้ unit ผ่านทาง interface ต่าง ๆ แล้วทดสอบว่าสิ่งที่ unit ตอบสนองนั้นตรงตามต้องการหรือเปล่า

ลองดูตัวอย่างก่อนเลยดีกว่า สมมติว่าเรามีฟังกชัน countMultiplesInRange ที่รับจำนวนเต็ม a และช่วงของจำนวนเต็มจาก f ถึง t ให้หาจำนวนของจำนวนเต็มตั้งแต่ f จนถึง t (รวมหัวท้ายด้วย) ที่ a หารลงตัว

ส่วนโครงของฟังก์ชันแสดงด้านล่างครับ (เนื่องจากเขียนด้วย Java ต่อไปจะเรียกฟังก์ชันดังกล่าวว่าเมท็อด)

public class Divisibility {

    public static int countMultiplesInRange(int a, int f, int t) {
        // should return the number of integers
        //   from a to f (inclusive) divisible by a

        // ... some implementation here
    }
}

สังเกตว่าเราไม่สนใจว่าข้างในเมท็อดดังกล่าวมีข้างในอย่างไร ถ้าจะเขียนจริง ๆ คงต้องสนใจ แต่ตอนนี้สนแค่หน้าตา (interface) ของมันก็พอ

เราจะเริ่มโดยการทดสอบกรณีง่าย ๆ ก่อน โดยทดสอบกรณีที่ช่วงเริ่มที่ 0 และ a หารขอบอีกด้านไม่ลงตัว

สำหรับคนที่ใช้ IDE เช่น Eclipse หรือ Netbeans เวลาจะสร้าง JUnit test ส่วนมากก็สามารถทำได้โดยกดเลือกเอาได้เลย (อาจต้องมีการเพิ่ม library ก่อนตอนสร้าง project) สำหรับตัวอย่างต่อ ๆ ไป เราจะเขียนโดยสมมติว่าใช้ JUnit4

ด้านล่างแสดง junit test ของเมท็อดดังกล่าวในกรณีแรก สังเกตว่าเราต้อง import org.junit.Test (เพื่อ annotation @Test) และ import static org.junit.Assert เพื่อคำสั่งในการตรวจสอบค่า

import org.junit.Test;
import static org.junit.Assert.*;

public class DivisibilityTest {
	@Test
	public void testRangeFromZero() {
		int res = Divisibility.countMultiplesInRange(3, 0, 10);
		assertEquals(4,res);
	}
}

เราระบุให้ JUnit ทราบว่าเมท็อดใดในคลาสสำหรับทดสอบเป็น testcase โดยการแปะ @Test ไว้ด้านหน้า ในตัวอย่างข้างต้น เราเรียกใช้เมท็อด Divisibility.countMultiplesInRange แล้วใช้คำสั่ง assertEquals ในการตรวจคำตอบว่าผลลัพธ์ที่ได้สอดคล้องกับที่เราคาดเอาไว้หรือไม่

นอกจากกรณีง่ายแล้ว เรายังมีอีกหลายกรณีที่ต้องทดสอบเมท็อดดังกล่าว (เนื่องจากเขียนผิดได้ง่ายมาก) ยกตัวอย่างเช่น กรณีที่ขอบซ้ายของช่วงเป้นจำนวนลบ ขณะที่ขอบขวาเป็นบวกเป็นต้น

เรายังสามารถหาชุดข้อมูลทดสอบได้อีกมากมายไม่รู้จบ แต่เราควรจะเลือกชุดข้อมูลที่ทำให้เรามีโอกาสเจอข้อผิดพลาดของโปรแกรมได้มาก คราวหน้ากลับมาพร้อมกับแนวทางในการเลือกชุดข้อมูลทดสอบครับ

Comment

Comment:

Tweet

ขอบคุณสำหรับ comment นะครับ

คุณ plynoi: ผมใช้คล้าย ๆ ที่คุณ deans4j บอกอ่ะครับ คือตรงไหนดูเสี่ยง ก็ใช้อ่ะครับ ;)

veer: ผมก็ชอบเหมือนกันครับ

xnanoob: http://code.google.com/p/syntaxhighlighter/ ถ้าลองแล้วเซ็ตไม่ได้บอกนะ

คุณ deans4j: สบายครับ ผมก็เดินไปเดินมา ไม่ได้ฟังอะไรเป็นเรื่องเป็นราวเท่าไหร่อ่ะครับ ;) เท่าที่ดู TestNG มีอะไรเยอะกว่าจริง ๆ ครับ สำหรับคนเริ่มต้น JUnit (ที่เหมือนจะง่ายกว่า) น่าจะโอเคนะครับ (หรือเปล่า? อิอิ)

#5 By wonam on 2008-09-01 08:31

สวัสดีครับ อ. ก่อนอื่นต้องขอโทษที่ในงาน #barcampbangkok2 ไม่ค่อยได้คุยกัน เห็นอ. ดูยุ่งๆ :D

ช่วยเสริมครับ ใน Java จะมี unit test tool อีกตัวหนึ่งชื่อว่า TestNG อ่านสั้นๆว่า เทสติง หรือบางคนก็อ่าน เทสเอนจี ตัว NG ย่อมาจาก next generation

ตัวนี้จะเก่งกว่า JUnit พอสมควร ออกมาในยุค JUnit 3 เลยเห็นความแตกต่างค่อนข้างชัดเจน ว่า TestNG มีอะไรให้ใช้มากกว่า พอยุค JUnit 4 ก็เลยได้รับแรงบันดาลใจกลับคืน :D แต่คิดว่ายังไง TestNG ก็ยังมีลูกเล่นมากกว่าอยู่ดี (ไม่ได้เช็กเอกสาร JUnit4 เท่าไหร่)big smile

#4 By deans4j (124.120.133.237) on 2008-09-01 02:04

อ.ใช้ไรวางโค้ดอะ ... สอนมั่งดิ

#3 By xnanoob on 2008-08-31 22:40

พอมี annotation แล้วผมรีบใช้ junit4 เลยครับ ชอบมาก confused smile

#2 By veer on 2008-08-31 12:17

ใช้ไม่เป็นเลย
Dev ทีมผมก็ไม่ได้ใช้ด้วย sad smile sad smile
ขอบคุณมากครับ

#1 By plynoi แว่วศรี on 2008-08-31 09:37