使用 TimedTest


在單元測試功能無誤之後,若想對方法作效能量測,在JUnit 4.x中,可以藉由設定@Testtimeout屬性,指定方法必須在限定時間內完成,否則測試失敗。例如,測試 資料庫單元測試 中BookmarkDAOImpl的get()與add()方法耗費時間:
package test.cc.openhome;

import org.junit.Before;
import org.junit.Test;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import cc.openhome.dao.BookmarkDAO;
import cc.openhome.dao.BookmarkDAOImpl;
import cc.openhome.model.Bookmark;

public class BookDAOImplPerfTest {
private BookmarkDAO dao;

@Before
public void setUp() throws Exception {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/exercise");
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.getConnection().close(); // 為了先載入驅動程式
dao = new BookmarkDAOImpl(dataSource);
}

@Test(timeout = 100)
public void testGet() {
dao.get();
}

@Test(timeout = 100)
public void testAdd() {
Bookmark bookmark = new Bookmark("http://m", "n", "o");
dao.add(bookmark);
}
}

如果使用的是JUnit 3.x,則可以使用 JUnitPerfTimedTest類別,這個類別實作了junit.framework.Test介面,以  Decorator 模式 的方式,對TestCase增加逾時測試的功能。例如:
package test.cc.openhome;

import com.clarkware.junitperf.TimedTest;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import cc.openhome.dao.BookmarkDAO;
import cc.openhome.dao.BookmarkDAOImpl;
import cc.openhome.model.Bookmark;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class BookDAOImplPerfTest extends TestCase {
private BookmarkDAO dao;

public BookDAOImplPerfTest(String name) throws Exception {
super(name);
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/exercise");
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.getConnection().close(); // 為了先載入驅動程式
dao = new BookmarkDAOImpl(dataSource);
}

public void testGet() {
dao.get();
}

public void testAdd() {
Bookmark bookmark = new Bookmark("http://m", "n", "o");
dao.add(bookmark);
}

public static Test suite() throws Exception {
TestSuite suite = new TestSuite();
suite.addTest(new TimedTest(
new BookDAOImplPerfTest("testGet"), 150));
suite.addTest(new TimedTest(
new BookDAOImplPerfTest("testAdd"), 150));
return suite;
}
}


在建立TimedTest時,要傳入TestCase實例,並需指定要測試的方法,TimedTest會先運行指定的測試,接著量測花費的時間,預設情況下,TimedTest會等待指定的測試結束後,再判定花費時間是否超出預期,如果是就測試失敗,你也可以設定花費時間超出預期時,立即中斷測試,這是由TimedTest建構式的第三個建構式決定。例如:
    ...
    public static Test suite() throws Exception {
        TestSuite suite = new TestSuite();
        // false 表示 NON-WAITING
        suite.addTest(new TimedTest(     
                new BookDAOImplPerfTest("testGet"), 150, false));
        suite.addTest(new TimedTest(
                new BookDAOImplPerfTest("testAdd"), 150, false));
        return suite;
    }
    ...

要注意的是,TimedTest會連同setUp()、tearDown()的執行時間一併計算,所以為了得到較精確的執行時間,你要將setUp()、tearDown()的執行時間納入考量。