2009-09-18 97 views
21

我對測試的經典結構,我有不同的套件像DatabaseTests的測試套件,單元測試等,有時,這些套件包含其他套件一樣SlowDatabaseTests,FastDatabaseTests等如何讓我的JUnit測試以隨機順序運行?

我想是隨機的運行秩序所以我會確保他們不相互依賴。隨機化應該在每個級別上,像套件應該洗牌測試類的順序,測試類應該洗牌測試方法的順序。

如果可以在Eclipse中做到這一點,將是最好的。

+7

隨機化訂單不會證明任何事情,因爲隨機可能會「偶然」工作。此外,這不會是可重複的,所以你永遠無法追查失敗的原因。 – skaffman 2009-09-18 12:45:23

+3

如果我在每次測試運行的地方寫入執行命令,我將能夠跟蹤原因。 – nimcap 2009-09-18 14:02:03

+8

你可以通過給Random()一個沒有時間的日期函數的種子來重複它。如果您這樣做,我強烈建議持續構建,以便在測試失敗時注意。 – NamshubWriter 2009-09-29 15:25:07

回答

12

你有一個Sortable,但我看不到你將如何使用它。

您可以擴展BlockJUnit4ClassRunner並讓computeTestMethods()返回super.computeTestMethods()的隨機副本。然後使用@RunWith將其設置爲要使用的跑步者。

例如

package com.stackoverflow.mlk; 

import java.util.Collections; 

import org.junit.runners.BlockJUnit4ClassRunner; 
import org.junit.runners.model.InitializationError; 

public class RandomBlockJUnit4ClassRunner extends BlockJUnit4ClassRunner { 

    public RandomBlockJUnit4ClassRunner(Class<?> klass) 
      throws InitializationError { 
     super(klass); 
    } 

    protected java.util.List<org.junit.runners.model.FrameworkMethod> computeTestMethods() { 
     java.util.List<org.junit.runners.model.FrameworkMethod> methods = super.computeTestMethods(); 
     Collections.shuffle(methods); 
     return methods; 
    } 

} 

然後

@RunWith(com.stackoverflow.mlk.RandomBlockJUnit4ClassRunner.class) 
public class RandomOrder { 
    @Test 
    public void one() { 
    } 

    @Test 
    public void two() { 
    } 

    @Test 
    public void three() { 
    } 
} 
+0

很好的答案,但還不夠充分我需要實現一個套件跑步者,以隨機化測試類的順序。除此之外,我還有很多測試,我不想將@RunWith註釋放入其中。我認爲這可以在套件跑步者 – nimcap 2009-10-05 10:58:51

+2

中處理,我發現這非常有用,並且我創建了一個隨機測試和套件的小型Java項目。欲瞭解更多信息,請訪問其網頁:http://randomjunit.sourceforge.net/ – AngocA 2011-06-24 06:32:14

0

我會確保它們不依賴於 相互

你應該確保這是不依賴於隨機執行順序的情況。是什麼讓你擔心依賴可能存在?

+0

我可以問爲什麼人們低估了我的答案?它有什麼問題? – 2009-09-18 12:45:36

+5

我們在編寫單元測試並使其獨立時非常小心。但是我們也非常小心地編寫生產代碼,錯誤發生,並不能保證它們會獨立。 PS:我們不僅使用JUnit進行單元測試,而且還使用JUnit進行功能測試,所以它們有時會使數據庫處於某種狀態。 – nimcap 2009-09-18 14:05:12

+5

@lutz我想是因爲你在回答OP的問題時反駁了另一個問題 – akuhn 2009-09-19 21:27:03

3

一般來說,你需要做的是編寫你自己的測試運行器,並在測試運行器類中聚合這些方法並隨機運行每個測試(確保不要運行兩次測試)。

瞭解更多關於測試框架以及如何在這裏寫你自己的測試亞軍: http://www.ddj.com/architect/184415674

+0

請注意,ddj.com文章介紹了JUnit3測試運行器。如果您嘗試這樣做,請注意,如果您的測試使用TestSetup或嘗試執行套件級別的設置並通過擴展TestSuite來拆除,則此處建議的方法將不起作用;測試運行者不會「看到」TestSuites或TestDecorators。編寫自己的JUnit3測試運行器也不會工作,如果您從IDE等IDE運行測試。 – NamshubWriter 2009-09-29 15:35:36

4

https://github.com/KentBeck/junit/pull/386介紹了一些訂單,但不RANDOM。可能你並不是真的想要這樣;測試應確定性地運行。如果您需要驗證不同排列的測試仍然通過,請測試所有排列;或者,如果這樣做不切實際,則引入一個由隨機變量或類似因素決定的「隨機」種子,以便重現任何失敗。 http://hg.netbeans.org/main/file/66d9fb12e98f/nbjunit/src/org/netbeans/junit/MethodOrder.java舉例說明如何爲JUnit 3執行此操作。