[Junit] 测试方法执行顺序

引用自:http://www.cnblogs.com/lukehuang/p/3284766.html,以作备忘。谢谢原作者的知识分享。

[size=x-large]Brief[/size]

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

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

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

当没有指定任何顺序时,按默认来执行。

[size=x-large]Sorters[/size]

1. MethodSorters.DEFAULT
默认顺序由方法名hashcode值来决定,如果hash值大小一致,则按名字的字典顺序确定。

由于hashcode的生成和操作系统相关(以native修饰),所以对于不同操作系统,可能会出现不一样的执行顺序,在某一操作系统上,多次执行的顺序不变。


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)

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里尤其如此).

[size=x-large]Samples[/size]

以下是对Win7 - JDK7 - Junit4.11 的执行结果

@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

结果始终为:
[table]
|test002Second|
|test001Second|
|test003Second|
[/table]

2. NAME_ASCENDING

结果始终为:
[table]
|test001Second|
|test002Second|
|test003Second|
[/table]

3. JVM

多数情况下 结果为:
[table]
|test002Second|
|test001Second|
|test003Second|
[/table]
偶尔出现:
[table]
|test001Second|
|test003Second|
|test002Second|
[/table]

[size=x-large]Dig more ..[/size]

实际上 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;
}


三种执行顺序的定义如下:

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测试方法的执行顺序也不是确定的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值