From Gossip@caterpillar

JUnit Gossip: TestCase

使用JUnit時,您主要都是透過繼承TestCase類別來撰寫測試案例,預設上您可以使用testXXX() 名稱來撰寫單元測試。

在測試一個單元方法時,有時您會需要給它一些物件作為運行時的資料,例如您撰寫下面這個測試案例:

  • MaxMinTest.java
package onlyfun.caterpillar.test;

import onlyfun.caterpillar.MaxMinTool;
import junit.framework.TestCase;

public class MaxMinTest extends TestCase {
public void testMax() {
int[] arr = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
assertEquals(5, MaxMinTool.getMax(arr));
}

public void testMin() {
int[] arr = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
assertEquals(-5, MaxMinTool.getMin(arr));
}

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

您將設計的MaxMinTool包括靜態方法getMax()與getMin(),當您給它一個整數陣列,它們將個別傳回陣列中的最大值與最小值,顯然 的,您所準備的陣列重複出現在兩個單元測試之中,重複的程式碼在設計中可以減少就儘量減少,在這兩個單元測試中,整數陣列的準備是單元方法所需要的資源, 我們稱之為fixture,也就是一個測試時所需要的資源集合。

fixture必須與上下文(Context)無關,也就是與程式執行前後無關,這樣才符合單元測試的意涵,為此,通常將所需的fixture撰寫在單元方法之中,如此在單元測試開始時創建fixture,並於結束後銷毀fixture。

然而對於重複出現在各個單元測試中的fixture,您可以集中加以管理,您可以在繼承TestCase之後,重新定義setUp()tearDown()方法,將數個單元測試所需要的fixture在setUp()中創建,並在tearDown()中銷毀,例如:

  • MaxMinTest.java
package onlyfun.caterpillar.test;

import onlyfun.caterpillar.MaxMinTool;
import junit.framework.TestCase;

public class MaxMinTest extends TestCase {
private int[] arr;

protected void setUp() throws Exception {
super.setUp();
arr = new int[]{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
}

protected void tearDown() throws Exception {
super.tearDown();
arr = null;
}

public void testMax() {
assertEquals(5, MaxMinTool.getMax(arr));
}

public void testMin() {
assertEquals(-5, MaxMinTool.getMin(arr));
}

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

setUp()方法會在每一個單元測試testXXX()方法開始前被呼叫,因而整數陣列會被建立,而tearDown()會在每一個單元測試 testXXX()方法結束後被呼叫,因而整數陣列參考名稱將會參考至null,如此一來,您可以將fixture的管理集中在 setUp()與tearDown()方法之後。

最後按照測試案例的內容,您完成MaxMinTool類別:

  •  MaxMinTool.java
package onlyfun.caterpillar;

public class MaxMinTool {
public static int getMax(int[] arr) {
int max = Integer.MIN_VALUE;

for(int i = 0; i < arr.length; i++) {
if(arr[i] > max)
max = arr[i];
}

return max;
}

public static int getMin(int[] arr) {
int min = Integer.MAX_VALUE;

for(int i = 0; i < arr.length; i++) {
if(arr[i] < min)
min = arr[i];
}

return min;
}
}

Swing介面的TestRunner在測試失敗時會顯示紅色的棒子,而在測試成功後會顯示綠色的棒子,而 "Keep the bar green to keep the code clean." 正是JUnit的名言,也是測試的最終目的。