后,還有個org.jboss.jrunit.TestDriver類,用于表示客戶端和服務器端測試的“驅動”。這個類可以產生新的test harness,把客戶端和服務器端的test case放在里面跑。這個測試驅動可以通過一個JGroup消息總線與那些test harness進行通訊,從而控制服務器和所有客戶端的test case,并從它們那里獲得測試結果
邏輯上,運行一個由test runner控制的測試的順序如下:
(The logical order of a test run as controlled by the test runner is: )
(譯注:這個test runner可能是指剛才所說的driver)
1.為每個客戶端和服務器端test case生成一個新的test harness
2.等待確認,直至所以test harness創建完畢,它們各自的消息總線也已經啟動
3.一旦收到確認,會等待服務器端的test case啟動(比如,調用服務器test case的setUp方法)。否則,假如沒有收到確認,殺死所以進程,返回出錯信息給JUnit。(譯注:可見jrunit只是junit的一個擴展,底層還是依賴于junit的實現,比如錯誤提示)
4.確認服務器端啟動完畢后,通知所有的test case(客戶端和服務器的)開始運行。否則(如果沒有確認信息),對所有test harness發送退出信息。
5.等待客戶端test case的結果
6.一旦收到全部客戶端返回的結果,通知服務器進行tear down(例如,調用服務器test case的teardown方法)。否則,殺死所以進程返回出錯信息給JUnit
7.等待服務器端的測試結果(當然服務器test case要有test方法)
8.處理所有測試結果,提交給JUnit TestResult類,測試結果會以普通Junit測試報告的方式呈現出來。
9.等待服務器關閉的信息,表明服務器已經成功地關閉并清理完資源
10.關閉消息總線和根測試(root test run),返回至Junit的執行線程中。
對于test driver,用戶需要進行編碼的地方是實現一個繼承自org.jboss.jrunit.TestDriver的抽象類,并實現其中的declareTestClasses()方法。在這個方法內部調用TestDriver類的addTestClasses方法,并且指定客戶端test case類、客戶端的并發數量以及服務器端test case類
基準修飾符(Benchmark Decorator)
JRunit使用基準修飾符來提供除了普通Junit測試結果外的一些數據,稱為基準結果
org.jboss.jrunit.decorators.ThreadLocalDecorator(以及其他可以接收線程個數和循環次數(等參數)的修飾符)——指定多少個線程數,會有多少個執行同一個測試的線程被創建。指定多少次循環,會在每個測試實例中,對每個測試方法循環那么多次。比如,如果指定3個線程、10次循環,那么將會有三個線程執行該測試用例(也即創建了三個測試實例),每個測試實例中,會將里面的所以test方法執行10遍。下面是一個相關的例子:
public class SimpleThreadLoopCounter extends TestCase
{
private static int staticCounter = 0;
private static int staticMethodCounter = 0;
private int localCounter = 0;
public static Test suite()
{
return new ThreadLocalDecorator(SimpleThreadLoopCounter.class, 3, 10, 0, true, true);
}
public SimpleThreadLoopCounter()
{
staticCounter++;
}
public void testCounter() throws Exception
{
System.out.println("staticCounter = " + staticCounter);
System.out.println("staticMethodcounter = " + ++staticMethodCounter);
System.out.println("localCounter = " + ++localCounter);
}
}
運行這個例子,后的輸出會是:
staticCounter = 3 staticMethodcounter = 30 localCounter = 10
有個問題是關于junit如何處理多個test方法(譯注:具體方式在開頭已經有所說明)。對于每個test case中的每個test方法,junit都會創建一個新的測試實例來運行這個方法。為了說明這一點,我們復制上面代碼的testCounter方法(把復制后的改名為testCounter2),那么在輸出結果中后一行變為:
staticCounter = 6 staticMethodcounter = 60 localCounter = 10
(譯注:指定了三個線程,junit又為每個測試類創建兩個實例,所以總共3×2個,但是對于每一個,它的localCounter 還是10,即執行了10次循環)
JRUnit和修飾符的注意事項:如果numberOfThreads大于1,那ServerTestHarness不會運行。但是numberOfThreads可以拿來模擬同一時刻并發的客戶端數量,從這個意義上來說,我認為這不算是個大問題。如果要用ServerTestHarness來這么做,事實上也的確可以產生多個客戶端。即時這些客戶端不是在一個進程中并發運行,起碼也是在各個單獨的進程中并發。而能夠設定循環變量也是很有必要的,雖然這樣會讓客戶端額外地調用服務器一段時間(或者反復調用)。因此,如果進行遠程測試并且要用ThreadLocalDecorator獲取基準數據的話,你可以使用下面這個ThreadLocalDecorator的構造器,它的線程數是默認為1的
public ThreadLocalDecorator(Class testClazz, int loops)