JUnit 中提供了三种方式来决定执行顺序
- MethodSorters.NAME_ASCENDING 按照测试方法的方法名的字母表顺序进行排序
- MethodSorters.JVM 交由 JVM 决定执行顺序
- MethodSorters.DEFAULT 按照测试方法的方法名的 hashcode 进行排序,这个为默认值
具体实现可在 org.junit.internal.MethodSorter 中找到,可以通过在测试用例类上添加 FixMethodOrder 注解来改变默认值。但这种方式不能按照指定的顺序执行测试用例,下面提供一个方法来实现这个功能。
- 定义
Order
注解,来指定测试用例的执行顺序
package net.saisimon.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
int value() default 0;
}
- 继承 JUnit 的
org.junit.runners.BlockJUnit4ClassRunner
运行器,来重新实现获取测试用例顺序的方法,如果是测试 Spring 应用,可继承org.springframework.test.context.junit4.SpringJUnit4ClassRunner
运行器
package net.saisimon.test;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
// Spring
// import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
// JUnit
import org.junit.runners.BlockJUnit4ClassRunner;
// Spring 继承
// public class OrderedRunner extends SpringJUnit4ClassRunner {
// JUnit 继承
public class OrderedRunner extends BlockJUnit4ClassRunner {
// 测试用例的方法集合
private static List<FrameworkMethod> testMethodList;
public OrderedRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
// 重写 computeTestMethods 方法,按指定顺序排序
@Override
protected List<FrameworkMethod> computeTestMethods() {
if (testMethodList == null) {
testMethodList = super.computeTestMethods().stream()
.sorted((m1, m2) -> {
// 根据测试用例上的 Order 注解来决定执行顺序
Order o1 = m1.getAnnotation(Order.class);
Order o2 = m2.getAnnotation(Order.class);
if (o1 == null || o2 == null) {
return 0;
}
return o1.value() - o2.value();
}).collect(Collectors.toList());
}
return testMethodList;
}
}
- 测试用例,使用
Order
注解来决定执行顺序
package net.saisimon.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import net.saisimon.annotation.Order;
@RunWith(OrderedRunner.class)
public class OrderedRunnerTest {
@Test
@Order(1)
public void test2() {
System.out.println(2);
}
@Test
@Order(2)
public void test1() {
System.out.println(1);
}
@Test
@Order(3)
public void test3() {
System.out.println(3);
}
// 输出
// 2
// 1
// 3
}