java fixmethodorder_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 DEFAULT = new Comparator() {

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 NAME_ASCENDING = new Comparator() {

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 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代码  c3f713bc49f7d3c749d0ee3bca7960fe.png

import org.junit.FixMethodOrder;

import org.junit.Test;

import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)

public class OrderedTestCasesExecution {

@Test

public void test001First() {

System.out.println("Executing first test");

}

@Test

public void test002Second() {

System.out.println("Executing second test");

}

@Test

public void test003Third() {

System.out.println("Executing third test");

}

}

输出:

Executing first test

Executing second test

Executing third test

好的,关于 Java 参数化测试JUnit 提供了参数化测试的功能,可以让我们更方便地编写测试用例。在 JUnit 中,参数化测试使用 @RunWith(Parameterized.class) 注解标记测试类,并使用 @Parameter 注解标记测试方法中每个参数的值。具体步骤如下: 1. 创建一个测试类,并使用 @RunWith(Parameterized.class) 注解标记该类。 2. 声明一个静态方法,该方法返回一个集合,集合中的每个元素都是一个数组,表示测试方法中的参数。 3. 在测试类的构造方法中,使用 @Parameter 注解标记测试方法中每个参数的值。 4. 编写测试方法,使用测试方法中的参数运行测试用例。 例如,下面是一个简单的参数化测试示例: ``` @RunWith(Parameterized.class) public class CalculatorTest { private int a; private int b; private int expected; public CalculatorTest(int a, int b, int expected) { this.a = a; this.b = b; this.expected = expected; } @Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { { 1, 2, 3 }, { 3, 4, 7 }, { 5, 6, 11 } }); } @Test public void testAdd() { Calculator calculator = new Calculator(); int result = calculator.add(a, b); assertEquals(expected, result); } } ``` 在上面的示例中,我们使用 @Parameters 注解标记了一个静态方法 data(),该方法返回一个集合,集合中包含了每个测试用例的参数值。在测试类的构造方法中,使用 @Parameter 注解标记了测试方法中的每个参数,这些参数会在测试方法被调用时传递给测试方法。在测试方法中,我们使用传递过来的参数运行测试用例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值