JUnitPerf 是建立在 JUnit 之上的效能測試擴充框架,讓開發者能以撰寫單元測試的方式,自動化執行響應時間與吞吐量驗證。它不是取代 LoadRunner/JMeter 等專業壓測工具,而是在「重構保護網」層面提供持續的效能回歸守護。
// 基本用法:等待測試完成,超過 maxElapsedTime 則失敗
long maxElapsedTime = 1000; // 1秒
Test testCase = new ExampleTestCase("testOneSecondResponse");
Test timedTest = new TimedTest(testCase, maxElapsedTime);
// 進階:超時即終止 (fail-fast),第三參數 false 表示不等待完成
Test timedTestFastFail = new TimedTest(testCase, maxElapsedTime, false);
計時範圍:包含 `setUp()` + `testXXX()` + `tearDown()` 總時間。設定閾值時務必預留 fixture 耗時。
// 基本:10 用戶並發各執行 1 次
int users = 10;
Test loadTest = new LoadTest(testCase, users);
// 帶延遲:ConstantTimer (固定延遲) / RandomTimer (隨機延遲)
Timer timer = new ConstantTimer(1000); // 1秒間隔
Test loadTestWithDelay = new LoadTest(testCase, users, timer);
// 多次迭代:每用戶執行 20 次
int iterations = 20;
Test repeatedTest = new RepeatedTest(testCase, iterations);
Test loadTestIterated = new LoadTest(repeatedTest, users, timer);
// 簡寫:LoadTest(testCase, users, iterations, timer)
Test loadTestCompact = new LoadTest(testCase, users, iterations, timer);
// 有狀態測試:每執行緒獨立實例 (TestFactory / TestMethodFactory)
Test factory = new TestFactory(ExampleStatefulTest.class);
Test loadTestStateful = new LoadTest(factory, users);
public static Test suite() {
int maxUsers = 10;
long maxElapsedTime = 1500;
Test testCase = new ExampleTestCase("testOneSecondResponse");
Test loadTest = new LoadTest(testCase, maxUsers);
Test timedTest = new TimedTest(loadTest, maxElapsedTime); // 外層計時
return timedTest;
}
public static Test suite() {
int maxUsers = 10;
long maxElapsedTime = 1000;
Test testCase = new ExampleTestCase("testOneSecondResponse");
Test timedTest = new TimedTest(testCase, maxElapsedTime); // 內層計時
Test loadTest = new LoadTest(timedTest, maxUsers); // 外層併發
return loadTest;
}
public class ExamplePerfTestSuite {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(ExampleTimedTest.suite());
suite.addTest(ExampleLoadTest.suite());
return suite;
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
}
| 模式 | 行為 | 適用場景 |
|---|---|---|
| Waiting (預設) | 超時仍等待測試完成,累積所有結果再判定 | 單元測試需完整執行驗證副作用 (如資料庫狀態) |
| Non-Waiting (fail-fast) | 超時即中止,標記失敗,節省時間 | 明確 SLA、長時間跑不出結果即判定失效 |
| 模式 | 執行緒等待策略 | 適用場景 |
|---|---|---|
| Non-Atomic (預設) | 僅等待 LoadTest 直接衍生的執行緒 | 被測程式碼同步完成、無背景執行緒 |
| Atomic (setEnforceTestAtomicity(true)) | 等待同一 ThreadGroup 所有執行緒完成 | EJB 非同步查詢、背景任務、事件總線處理 |
# Windows
set JUNITPERF_HOME=C:\path\to\junitperf
set CLASSPATH=%CLASSPATH%;%JUNITPERF_HOME%\lib\junitperf-1.9.jar
# Unix/Linux
export JUNITPERF_HOME=/path/to/junitperf
chmod -R a+x $JUNITPERF_HOME
export CLASSPATH=$CLASSPATH:$JUNITPERF_HOME/lib/junitperf-1.9.jar
# Ant 建置與驗證
cd $JUNITPERF_HOME
ant jar # 建置
ant test # 執行內建測試驗證安裝
JUnitPerf 的核心哲學:「效能也是功能的一種,應該像功能測試一樣被自動化、被版本化、被持續驗證。」