zoukankan      html  css  js  c++  java
  • Junit之测试顺序---FixMethodOrder

    参考:http://www.cnblogs.com/lukehuang/archive/2013/08/27.html

    Brief
    Junit 4.11里增加了指定测试方法执行顺序的特性

    测试类的执行顺序可通过对测试类添加注解 “@FixMethodOrder(value)” 来指定,其中value 为执行顺序

    三种执行顺序可供选择:默认(MethodSorters.DEFAULT),按方法名(MethodSorters.NAME_ASCENDING)和JVM(MethodSorters.JVM)

    当没有指定任何顺序时,按默认来执行
    Sorters
    1. MethodSorters.DEFAULT
    默认顺序由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定
    由于hashcode的生成和操作系统相关(以native修饰),所以对于不同操作系统,可能会出现不一样的执行顺序,在某一操作系统上,多次执行的顺序不变
    实现代码:

    复制代码
    /**
         * 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 (推荐)
    按方法名称的进行排序,由于是按字符的字典顺序,所以以这种方式指定执行顺序会始终保持一致;
    不过这种方式需要对测试方法有一定的命名规则,如 测试方法均以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里尤其如此).
    Samples
    以下是对Win7 - JDK7 - Junit4.11 的执行结果

    复制代码
    //@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测试方法的执行顺序也不是确定的


    ---------------------------------------------------------------------
    例子:
     

    Java代码  收藏代码
    1. import org.junit.FixMethodOrder;  
    2. import org.junit.Test;  
    3. import org.junit.runners.MethodSorters;  
    4.   
    5. @FixMethodOrder(MethodSorters.NAME_ASCENDING)  
    6. public class OrderedTestCasesExecution {  
    7.     @Test  
    8.     public void test001First() {  
    9.         System.out.println("Executing first test");  
    10.           
    11.     }  
    12.   
    13.     @Test  
    14.     public void test002Second() {  
    15.       
    16.         System.out.println("Executing second test");  
    17.     }  
    18.   
    19.     @Test  
    20.     public void test003Third() {  
    21.         System.out.println("Executing third test");  
    22.     }  
    23. }  



    输出:
      Executing first test
    Executing second test
    Executing third test

  • 相关阅读:
    判断是否是三角形,三角形面积,三角形内外切圆半径和面积
    输入从a加到b的两个数字
    九九乘法表
    某公司销售员工的年终奖根据该员工的年销售总额s提成,年销售总额超过1万元才提成,超过部分提成比例如下:
    判断是否是闰年?
    从键盘上输入三个点的坐标值(1,1)、(2,4)、(3,2),编程求该三角形的面积。
    输入一个正方形的边长,输出正方形的外接圆和内接圆的面积。
    .输入一个4位正整数,以相反的次序输出,例如,输入1234,输出为4321。
    SecoClient在win10系统中连接失败解决方案
    PHP 关于判断输入日期是否合法
  • 原文地址:https://www.cnblogs.com/avivahe/p/5459565.html
Copyright © 2011-2022 走看看