事實上,在 關於 TestCase 的後半段介紹中,已經有點自訂TestRunner的意味,所謂的TestRunner,無非就是呼叫Test介面實作物件上的run()方法,傳入TestResult實例收集測試的結果。
在 使用 TestSuite 最後的範例中,你也可以這麼作:
...
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new XXXTest("testABC")); // 執行testABC()方法
suite.addTest(YYYTest.suite()); // suite() 傳回 TestSuite實例
suite.addTestSuite(OOOTest.class); // 自動找出所有testXXX()方法
return suite;
}
public static void main(String[] args) {
TestResult result = new TestResult();
suite().run(result);
// 接著就看你取得TestResult如何呈現測試報告了
}
觀察文字模式的TestRunner,其run()方法無非也只是代你作了這些事:
static public TestResult run(Test test) {
TestRunner runner= new TestRunner();
return runner.doRun(test);
}
public TestResult doRun(Test test) {
return doRun(test, false);
}
protected TestResult createTestResult() {
return new TestResult();
}
public TestResult doRun(Test suite, boolean wait) {
TestResult result= createTestResult();
result.addListener(fPrinter);
long startTime= System.currentTimeMillis();
suite.run(result);
long endTime= System.currentTimeMillis();
long runTime= endTime-startTime;
fPrinter.print(result, runTime);
pause(wait);
return result;
}
上例中,資訊的收集,其實是由ResultPrinter負責(fPrinter參考的實例),其為TestListener的實作物件。
只不過,對於自訂TestRunner,JUnit提供了一個基礎類別BaseTestRunner,在這個類別中提供了一些讀取組態設定、指定名稱取得某個TestSuite實例的方便方法,讓你不用從頭開始撰寫這些方法。事實上,文字版本的TestRunner,就是繼承BaseTestRunner實作而來:
public class TestRunner extends BaseTestRunner {
...
}
...
}
觀察BaseTestRunner文字版的TestRunner之原始碼,你可以很快地學會自訂TestRunner,或者發現目前已有的TestRunner更多的使用方式。例如文字版的TestRunner,可以如下將測試結果存在檔案之中:
- CalculatorTest.java
package cc.openhome;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import java.io.*;
public class CalculatorTest extends TestCase {
private Calculator calculator;
public CalculatorTest() {}
public CalculatorTest(String name) {
super(name);
}
@Override
protected void setUp() {
calculator = new Calculator();
}
@Override
protected void tearDown() {
calculator = null;
}
public void testPlus() {
int expected = 5;
int result = calculator.plus(3, 2);
assertEquals(expected, result);
}
public void testMinus() {
int expected = 1;
int result = calculator.minus(3, 2);
assertEquals(expected, result);
}
public static void main(String[] args) throws IOException {
TestRunner runner = new TestRunner(
new PrintStream(
new FileOutputStream("calculator.test.log")));
runner.doRun(new TestSuite(CalculatorTest.class));
}
}