由於需要做自動化測試,所以需要比較完善的單元測試。但是又因為某些測試的執行依賴另外一個測試產生的結果,所以希望所寫的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的底層源碼。這篇隨筆如果有什么錯誤,歡迎大家留言指正!