参考: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. elasticsearch 分布式集群搭建

    elasticsearch环境搭建及单节点搭建可参考我的上一篇:http://www.cnblogs.com/xuwenjin/p/8745624.html 本文以Elaticsearch 6.2.2 ...

  2. __block和__weak修饰符的区别

    block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...

  3. WireShark 过滤 SSDP

    在局域网中使用wireshark抓包过滤http的时候经常会出现一些干扰协议,例如SSDP,使用过滤条件"http"有可能出现N多ssdp包,如下图所示: SSDP:Simple ...

  4. O(∩_∩)O~~

    1.在一切ac的路上,所以的难题都是纸老虎. 2.加油吧,少年.

  5. Codeforces Global Round1 简要题解

    Codeforces Global Round 1 A 模拟即可 # include <bits/stdc++.h> using namespace std; typedef long l ...

  6. AGC006C Rabbit Exercise

    传送门 设 \(f_{i,j}\) 表示兔子 \(i\) 在当前 \(j\) 轮的期望位置 对于一次操作 \(f_{i,j+1}=\frac{1}{2}(2f_{i-1,j}-f_{i,j})+\fr ...

  7. vue项目中引入bootstrap

    (1)引入Jquery文件,需要在bootstrap.min.js 之前引入. 1.npm install jquery --save-dev 2. plugins: [ new webpack.Pr ...

  8. HTML学习笔记《一》 ---- HTML基本认识

    HTML 基本认识 一.简介 1.HTML是超文本标记语言,标准通用标记语言下的一个应用,解释性语言. 2.“超文本”就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 3.超文本标记语言的 ...

  9. 线上Bug修复流程

  10. fuzz系列之libfuzzer

    前言 本文以 libfuzzer-workshop 为基础 介绍 libFuzzer 的使用. libFuzzer简介 libFuzzer 是一个in-process,coverage-guided, ...