zoukankan      html  css  js  c++  java
  • [uiautomator篇] 设置@test的执行顺序

    http://jackyrong.iteye.com/blog/2025609

    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 

  • 相关阅读:
    linux中如何修改文件夹的用户权限 chown命令
    httpserver
    协程
    进程和线程的区别和联系
    python线程的GIL问题(全局解释器锁)
    线程同步互斥的方法
    threading模块创建线程
    信号量(信号灯)
    信号通道
    内存共享
  • 原文地址:https://www.cnblogs.com/liuzhipenglove/p/7080559.html
Copyright © 2011-2022 走看看