JUnit測試控制@Test執行順序的三種方式小結

JUnit測試控制@Test執行順序

第一種

@FixMethodOrder(MethodSorters.JVM)

從上到下 執行@Test

第二種(推薦)

@FixMethodOrder(MethodSorters.NAME_ASCENDING) 

按方法名字順序執行@Test

第三種

@FixMethodOrder(MethodSorters.DEFAULT)

默認方法,不可預期

Junit測試方法保證執行順序

由於需要做自動化測試,所以需要比較完善的單元測試。但是又因為某些測試的執行依賴另外一個測試產生的結果,所以希望所寫的test case按照自己希望的順序來執行。

隨後博主查閱資料發現瞭FixMethodOrder註解,可以有三種方式可以控制test執行順序。

  /**
     * Sorts the test methods by the method name, in lexicographic order, with {@link Method#toString()} used as a tiebreaker
     */
    NAME_ASCENDING(MethodSorter.NAME_ASCENDING),
    /**
     * Leaves the test methods in the order returned by the JVM. Note that the order from the JVM may vary from run to run
     */
    JVM(null),
    /**
     * Sorts the test methods in a deterministic, but not predictable, order
     */
    DEFAULT(MethodSorter.DEFAULT);

大概上就是上面三種,很多大佬的博客上都對這幾種有講解以及示例,博主在這裡就不囉嗦瞭,下面說一下我的一些疑問以及發現。

當使用默認排序時

@FixMethodOrder(MethodSorters.DEFAULT)
public class testDemo{
    
    @Test
    public void B(){
        System.out.println("b");
    }
    @Test
    public void C(){
        System.out.println("c");
    }
    @Test
    public void A(){
        System.out.println("a");
    }
    @Test
    public void AB(){
        System.out.println("ab");
    }
    @Test
    public void AC(){
        System.out.println("ac");
    }
    @Test
    public void A1(){
        System.out.println("a1");
    }
}

輸出

a
b
c
a1
ab
ac

這隻是博主眾多測試結果中的一個,實際上與API中描述的“but not predictable”有所出入,執行的順序是可預期的。

因為觀察到,名字短的總排在前面,ascii碼小的總在前面,所以博主猜測有可能順序跟方法名字的字符串的hashcode有關的,於是加上hashcode方法輸出之後,得到結果:

方法A:65
方法B:66
方法C:67
方法A1:2064
方法AB:2081
方法AC:2082

所以可以得出結論,當單元測試使用默認執行順序的時候,測試方法執行的順序是跟測試方法名字符串的hashcode大小線性相關。

Junit執行時應該是把所有的有@test註釋的方法存到一個容器裡,然後交由jvm去一一執行(博主還沒來得及仔細去研讀Junit的源碼,這是本人的猜測)。那麼問題來瞭,這一系列的方法是在同一個線程下還是多個線程一起執行的呢?

其實從測試的執行順序可以控制不難猜出,多個測試方法是串行執行的,但是實踐才是檢驗真理的唯一標準。

代碼就不貼瞭,有興趣的同學可以自己寫一下看看,就是在第二順位執行的方法那裡讓他休眠一下,觀察是否也會阻塞第三個方法。

最終的結果也證明瞭猜想。

我現在看的還比較淺顯,有時間的話會去研讀Junit的底層源碼。以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet

推薦閱讀: