在單元測試功能無誤之後,若想對方法作效能量測,在JUnit 4.x中,可以藉由設定@Test的timeout屬性,指定方法必須在限定時間內完成,否則測試失敗。例如,測試 資料庫單元測試 中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,則可以使用 JUnitPerf 的TimedTest類別,這個類別實作了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()的執行時間納入考量。