3 การเทสหลายเคส


Parameterized คือเทสรันเนอร์ตัวหนึ่ง ที่จะสามารถรันเทสหลายๆครั้ง ตามที่ เราได้ใส่พารามิเตอร์ไป
จากรูป จะเป็นว่า มีการทดสอบ 4 ครั้ง (ตรงมุมล่างซ้าย) แต่ละครั้งก็จะทำการทดสอบกับค่าที่ถูกเตรียมไว้ในเทสเคส



โค๊ดสำหรับ FactorialParametersTest.Java

package test;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import util.Factorial;
@RunWith(value = Parameterized.class)
public class FactorialParametersTest
{
private int expected;
private int value;
@Parameters
public static Collection<Integer[]> value()
{
return Arrays.asList(new Integer[][] { { 1, 0 }, { 1, 1 }, { 720, 6 },
{ 120, 5 } });
}
public FactorialParametersTest(int expected, int value)
{
this.expected = expected;
this.value = value;
}
@Test
public void FactTest()
{
Factorial fact = new Factorial();
Assert.assertEquals(expected, fact.fact(value), 0);
}
}
view raw gistfile1.java hosted with ❤ by GitHub


ถ้าจะทำการเทสหลายๆค่า คลาสที่จะเทสต้อง บอกให้ Junit รู้ว่า
"นี่คุณ คลาสนี้นะ ไม่ใช่ การเทสแบบธรรมดาๆนะ แต่จะมีข้อมูลอยู่ชุดหนึ่งที่คุณ Junit ต้องเทสทั้งหมด"

ถั่วต้มแล้วครับ เราต้องบอกเขาโดยการใส่
@RunWith(value = Parameterized.class)
ไว้บ้างบน ก่อนเทสคลาส ตามบรรทัดที่ 14 (โค๊ดจาก GitHub)

จากนั้น Junit ก็จะยังไม่อ๋อในทันใด ยังถามเราต่อไปอีกว่า
"อ้าวไหนละ เทสเคสของคุณ ไม่เห็นมี @Parameters เลย"
ครับ เราก็ต้องบอกเขาอีกว่า @Parameters อยู่ที่ไหน ซึ่งเราก็ได้เตรียมเอาไว้ให้แล้วที่บรรทัด  20
พอถึงตรงนี้อาจจะไม่ชัดเจนนิดหนึ่ง ซึ่งก็คือฟังก์ชั่นซิกเนเจอร์ funciton signature ที่ Junit จะยอมรับ มีเพียงฟอร์แมตเดียวเท่านั้นที่ Junit จะยอมรับ นั่นก็คือ

public static Collection< อาเรย์ของชนิดข้อมูล >

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

< อาเรย์ของชนิดข้อมูล > ในที่นี้ของเราคือ Integer[] หรือก็คือ อาเรย์ 2 มิติของ Integer . อ่ะ ๆ !  อย่าเคลิ้มนะครับ Integer[] ไม่ใช่ อาเรย์ 2 มิติ แต่มีแค่มิติเดียว สองมิติต้องเป็น
Integer[][]

สามมิติต้องเป็น
Integer[][][]

สี่มิติต้องเป็น..... พอล่ะ ไม่เล่นนะ มีสาระหน่อย

ก็งี้แหลครับ ตกลงจำนวนข้อมูลใน array 1D ของเราต้องมีจำนวนเท่ากับพารามิเตอร์ของ constructor นะครับ นั่นก็คือ
( int expected, int value )

ซึ่งคุณจะเห็นว่า ตัวแรกนะ คือค่าที่ควรจะได้ และตัวหลังคือค่าที่เราจะเอาไปใส่ในฟังก์ชั่น fact(int n) จากคลาสของ Factorial.java

ที่ constructor ก็ไม่มีอะไรมาก แค่ตั้งค่าเฉยๆ this ไป this มา เพื่อให้
@Test
public void FactTest()
สามารถเรียกใช้งานได้ @Test นี่จะเป็นตัวบอกให้ Junit รู้ว่านี่จะเป็นฟังก์ชั่นที่เอาไว้ใช้ทดสอบกับชุดข้อมูล

อีกนิดหนึ่ง ตรงฟังก์ชั่น
@Parameters
public static Collection<Integer[]> value(){ .... }
คุณจะเก็บค่ายังไงก็ได้ แต่สุดท้ายต้องคืนค่า Collection ซึ่ง List ก็ทำการ extends Collection<E> เช่นกัน
นั่นหมายความว่า คุณสามารถเขียนแบบนี้ก็ได้

@Parameters
public static Collection<Integer[]> value()
{
List<Integer[]> x = new ArrayList<Integer[]>();
x.add(new Integer[]{1,0});
x.add(new Integer[]{1,1});
x.add(new Integer[]{2,2});
x.add(new Integer[]{120,5});
return x;
}
view raw gistfile1.java hosted with ❤ by GitHub


ทดสอบความกล้าหาญ


ในคลาส FactorialParametersTest.java คุณลองเขียนอีกฟังก์ชั่นหนึ่งที่มี @Test อยู่ด้วย แล้วลองรันดูว่าจะเกิดอะไรขึ้น