Dashboard > OpenSource Project > ... > JUnit > JUnit Intro - failure and error
OpenSource Project Log In   View a printable version of the current page.
JUnit Intro - failure and error
Added by koji lin, last edited by koji lin on Sep 27, 2004
Labels: 
(None)

Reference by JavaWorld,caterpillar


JUnit將測試不通過的結果區分為失敗(failure)與錯誤(error),失敗指的是斷言結果為false,也是您所預期應該成功的測試失敗了,而錯誤指的是意料之外的異常,這個異常是您沒有考慮到的,也許會造成程式的錯誤,或是程式的終止,例如ArrayIndexOutOfBoundsException就是一個錯誤。

有時候您設計好一個類別,在測試的時候您注重於一些斷言的測試,然而程式中可能有一些部份可能是您沒有考慮到的,JUnit的錯誤就是在幫您捕捉這些沒有考慮到的部份,我們使用一個簡單的例子作為說明,首先我們設計一個類別:

public class SimpleArray {
    private int[] _array;
        public SimpleArray() {
        _array = new int[10];
    }

    public SimpleArray(int length) {
        _array = new int[length];
    }

    public void set(int index, int value) {
        _array[index] = value;
    }

    public int get(int index) {
        return _array[index];
    }

    public int length() {
        return _array.length;
    }
}


為了測試這個簡單的類別,我們撰寫一個測試案例:

import junit.framework.TestCase;
public class SimpleArrayTest extends TestCase {
    private SimpleArray _simpleArray;
    public SimpleArrayTest(String arg0) {
        super(arg0);
    }
    protected void setUp() throws Exception {
        super.setUp();
        _simpleArray = new SimpleArray();
    }
    protected void tearDown() throws Exception {
        super.tearDown();
        _simpleArray = null;
    }
    public void testSetGet() {
        for(int i = 0; i < _simpleArray.length(); i++)
          _simpleArray.set(i, i);
        for(int i = 0; i < _simpleArray.length()+1; i++)
            assertTrue(i == _simpleArray.get(i));
    }
    public static void main(String[] args) {
        junit.textui.TestRunner.run(SimpleArrayTest.class);
    }
}


我故意在測式get()方法時存取超過陣列長度的元素,來看一下測試的結果如何?

.E
Time: 0.01
There was 1 error:
1) testSetGet(SimpleArrayTest)java.lang.ArrayIndexOutOfBoundsException: 10
        at SimpleArray.get(SimpleArray.java:17)
        at SimpleArrayTest.testSetGet(SimpleArrayTest.java:24)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at SimpleArrayTest.main(SimpleArrayTest.java:28)
FAILURES!!!
Tests run: 1,  Failures: 0,  Errors: 1


測試指出了一個錯誤,並告知了這個錯誤來自於存取超過陣列邊界,這表示您的這個類別最好為它加上邊界檢查了。

如果您的類別在執行某些功能時,指明必須處理某些例外,例如IOException,您可以在testXXXX()中使用try.....catch來處理它,或是將之丟出,由呼叫testXXXX()的來源來處理它,下面這個程式是個實例,假設java.io.FileReader是您所設計的類別,我們提供一個測試檔案test.txt,當中只撰寫了一個字元'1':

import java.io.*;
import junit.framework.TestCase;
public class FileReaderTest extends TestCase {
    private FileReader _reader;
    public FileReaderTest(String arg0) {
        super(arg0);
    }
    public void setUp() throws FileNotFoundException {
        _reader = new FileReader("test.txt");
    }
    public void tearDown() throws IOException {
        _reader.close();
    }
    public void testRead() throws IOException {
        assertTrue('1' == _reader.read());
    }
    public void testClose() throws IOException {
        _reader.close();
        try {
            _reader.read();
            fail("reading file after closed and didn't throw IOException");
        }
        catch(IOException e) {
        }
    }
    public static void main(String[] args) {
        junit.textui.TestRunner.run(FileReaderTest.class);
    }
}


注意到 testClose() 這個方法所進行的測試,有時候您所測試的可能是一個預期會丟出的例外,您想要看看當錯誤的情況成立時,是不是真會丟出例外,例如 testClose() 測試 FileReader 在 close() 之後如果再 read(),是不是會如期丟出IOException,我們先行在方法中用try....catch捕捉了這個例外,如果沒有如期丟出例外,則不會被catch捕捉,而程式流程繼續往下,執行到 fail() 陳述,這表示例外處理沒有發生,我們此時主動丟出一個失敗(failure),表示程式的執行並不如我們所預期的。

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.1.5a Build:#411 Mar 16, 2006) - Bug/feature request - Contact Administrators