[Junit] 測試方法執行順序

Junit 4.11裏增長了指定測試方法執行順序的特性
測試類的執行順序可經過對測試類添加註解 「@FixMethodOrder(value)」 來指定,其中value 爲執行順序
三種執行順序可供選擇:默認(MethodSorters.DEFAULT),按方法名(MethodSorters.NAME_ASCENDING)和JVM(MethodSorters.JVM)
當沒有指定任何順序時,按默認來執行java

Sorters

1. MethodSorters.DEFAULT數組

默認順序由方法名hashcode值來決定,若是hash值大小一致,則按名字的字典順序肯定ide

因爲hashcode的生成和操做系統相關(以native修飾),因此對於不一樣操做系統,可能會出現不同的執行順序,在某一操做系統上,屢次執行的順序不變測試

實現代碼:this

複製代碼
 /**
     * DEFAULT sort order
     */
    public static Comparator<Method> DEFAULT = new Comparator<Method>() {
        public int compare(Method m1, Method m2) {
            int i1 = m1.getName().hashCode();
            int i2 = m2.getName().hashCode();
            if (i1 != i2) {
                return i1 < i2 ? -1 : 1;
            }
            return NAME_ASCENDING.compare(m1, m2);
        }
    };
複製代碼

2. MethodSorters.NAME_ASCENDING (推薦) 按方法名稱的進行排序,因爲是按字符的字典順序,因此以這種方式指定執行順序會始終保持一致;spa

不過這種方式須要對測試方法有必定的命名規則,如 測試方法均以testNNN開頭(NNN表示測試方法序列號 001-999)操作系統

複製代碼
  /**
     * Method name ascending lexicographic sort order, with {@link Method#toString()} as a tiebreaker
     */
    public static Comparator<Method> NAME_ASCENDING = new Comparator<Method>() {
        public int compare(Method m1, Method m2) {
            final int comparison = m1.getName().compareTo(m2.getName());
            if (comparison != 0) {
                return comparison;
            }
            return m1.toString().compareTo(m2.toString());
        }
    };
複製代碼

3. MethodSorters.JVM 按JVM返回的方法名的順序執行,此種方式下測試方法的執行順序是不可預測的,即每次運行的順序可能都不同(JDK7裏尤爲如此).code

Samples

如下是對Win7 - JDK7 - Junit4.11 的執行結果blog

複製代碼
//@FixMethodOrder(MethodSorters.DEFAULT)
//@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
public class TestJunitOrder {

    @Test    
    public void test003Third() {        
        
        System.out.println("test003Third");
    }
    
    @Test    
    public void test001First() {        
        
        System.out.println("test001First");
    }
    
    @Test    
    public void test002Second() {        
        
        System.out.println("test002Second");
    }
}
複製代碼

1. DEFAULT排序

結果始終爲:

test002Second
test001First
test003Third

 

2. NAME_ASCENDING

結果始終爲:

test001First
test002Second
test003Third

 

3. JVM

多數狀況下 結果爲:

test002Second
test001First
test003Third

偶爾出現:

test001First
test003Third
test002Second

Dig more ..

實際上 Junit裏是經過反射機制獲得某個Junit裏的全部測試方法,並生成一個方法的數組,而後依次執行數組裏的這些測試方法;

而當用annotation指定了執行順序,Junit在獲得測試方法的數組後,會根據指定的順序對數組裏的方法進行排序;

複製代碼
  public static Method[] getDeclaredMethods(Class<?> clazz) {
        Comparator<Method> comparator = getSorter(clazz.getAnnotation(FixMethodOrder.class));//獲取測試類指定的執行順序

        Method[] methods = clazz.getDeclaredMethods();
        if (comparator != null) {
            Arrays.sort(methods, comparator);//根據指定順序排序
        }

        return methods;
    }
複製代碼

三種執行順序的定義以下:

複製代碼
 /**
     * 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);
複製代碼

由上能夠看出 當設置爲MethodSorters.JVM時,其並無提供一個Comparator的實現,因此執行方法的順序實際上就是 clazz.getDeclaredMethods();獲得的數組裏方法的順序,而因爲java裏對getDeclaredMethods返回的方法沒有指定任何順序,因此最終致使Junit測試方法的執行順序也不是肯定的

相關文章
相關標籤/搜索