参考: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测试方法的执行顺序也不是确定的

---------------------------------------------------------------------

例子:

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

输出:

  Executing first test

Executing second test

Executing third test

Junit之测试顺序---FixMethodOrder的更多相关文章

  1. JUnit源码分析 - 扩展 - 自定义Rule

    JUnit Rule简述 Rule是JUnit 4.7之后新加入的特性,有点类似于拦截器,可以在测试类或测试方法执行前后添加额外的处理,本质上是对@BeforeClass, @AfterClass, ...

  2. IDEA+JUnit

    1.入门 https://blog.csdn.net/smxjant/article/details/78206279 2.比较好的JUnit例子:https://github.com/aws/aws ...

  3. Java 单元测试顺序执行

    坑死我了,原来@Before会执行多次. 通过函数名可以实现顺序执行,执行顺序和函数的位置无关. import org.junit.Before; import org.junit.BeforeCla ...

  4. Springboot:单元测试@FixMethodOrder注解指定测试方法的执行顺序

    我们在写JUnit测试用例时,有时候需要按照定义顺序执行我们的单元测试方法,比如如在测试数据库相关的用例时候要按照测试插入.查询.删除的顺序测试.如果不按照这个顺序测试可能会出现问题,比如删除方法在前 ...

  5. Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式)介绍

    jedis是一个著名的key-value存储系统,而作为其官方推荐的java版客户端jedis也非常强大和稳定,支持事务.管道及有jedis自身实现的分布式. 在这里对jedis关于事务.管道和分布式 ...

  6. Test execution order

    刚开始的时候,JUnit并没有规定测试方法的调用执行顺序.方法通过映射的API返回的顺序进行调用.然 而,使用JVM顺序是不明智的,因为Java平台没有规定任何特定的顺序,事实上JDK7或多或少的返回 ...

  7. Java客户端Jedis的八种调用方式

      redis是一个著名的key-value存储系统,而作为其官方推荐的java版客户端jedis也非常强大和稳定,支持事务.管道及有jedis自身实现的分布式. 在这里对jedis关于事务.管道和分 ...

  8. JUnit4单元测试基础篇

    引言 JUnit作为Java语言的测试框架,在测试驱动开发(TDD)下扮演重要的角色.众所周知,无论开发大型项目还是一般的小型项目, 单元测试都至关重要.单元测试为软件可发测试维护提供了很大的便利.J ...

  9. SpringBoot单元测试中的测试方法执行顺序

    一.忽略方法@ignore 二.执行顺序@FixMethodOrder(MethodSorter.JVM) 我们在执行JUnit测试用例时,有时需要按照定义顺序执行单元测试方法,比如如在测试数据库相关 ...

随机推荐

  1. 利用SignalR来同步更新Winfrom小试

    之前写了个用Socket来更新多个Winfrom的试例,这两天看了下SignalR,也用这个来试一下 SignalR 地址:https://www.asp.net/signalr 我这个也是基于 ht ...

  2. JAVA编写简单的日历,输入日期即可查看日历

    利用LocalDate输入年月日找出当月日历 直接上代码 import java.time.LocalDate; import java.util.Scanner; public class Cale ...

  3. mysql 中 max_allowed_packet 查询和修改

    mysql 会根据配置文件限制 server 接收的数据包的大小. 有时候大的插入和更新会被 max_allowed_packet 参数限制,报如下错误: Packet > ). You can ...

  4. LOJ#6271. 「长乐集训 2017 Day10」生成树求和 加强版

    传送门 由于是边权三进制不进位的相加,那么可以考虑每一位的贡献 对于每一位,生成树的边权相当于是做模 \(3\) 意义下的加法 考虑最后每一种边权的生成树个数,这个可以直接用生成函数,在矩阵树求解的时 ...

  5. Django基础六之ORM中的锁和事务

    一 锁 行级锁 select_for_update(nowait=False, skip_locked=False) #注意必须用在事务里面,至于如何开启事务,我们看下面的事务一节. 返回一个锁住行直 ...

  6. HTMLcanvas矩形阵雨 - 学习笔记

    HTMLcanvas矩形阵雨 在画布上执行 获取制图环境 全屏获取屏幕宽度和屏幕高度 确定每个文字的宽度 以确定列 循环输出 定时器调用 HTML 部分 <!DOCTYPE HTML> & ...

  7. Web前端的状态管理

    背景 我相信很多朋友跟我一样,初次听到什么 Flux ,  Redux ,  Vuex , 状态管理 的时候是一脸懵逼的.因为在外面之前前端大部分开发的时候,根本没有那么多的概念.自从ReactJS火 ...

  8. leaflet 整合 esri

    此 demo 通过 proj4js 将 leaflet 与 esri 整合起来,同时添加了 ClusteredFeatureLayer 的支持. 下载 <html> <head> ...

  9. OpenGL学习--02--绘制一个红色三角形

    The OpenGL buffer is created, bound, filled and configured with the standard functions (glGenBuffers ...

  10. MapReduce:Shuffle过程详解

    1.Map任务处理 1.1 读取HDFS中的文件.每一行解析成一个<k,v>.每一个键值对调用一次map函数.                <0,hello you>   & ...