一般的做法是,自动化测试应该能够独立运行,没有特定的顺序,以及测试的结果不应该依赖于以前的测试结果。但在有些情况下,测试执行的特定顺序是合理的,特别是在集成或端到端的测试中。
默认情况下,在JUnit 5中,测试方法的执行在构建之间是可重复的,因此是确定性的,但该算法是故意不显眼的(正如库的作者所说)。幸运的是,执行顺序可以根据我们的需要使用内置的方法排序器或创建自定义的方法排序器来调整。
org.junit.jupiter.api.TestMethodOrder
为了改变测试执行顺序,我们需要用org.junit.jupiter.api.TestMethodOrder 注释测试类,并将方法排序器的类型作为一个参数传递。从JUnit 5.4开始,有三个内置的方法顺序器。OrderAnnotation,Alphanumeric 和Random 。我们也可以通过实现org.junit.jupiter.api.MethodOrderer 接口轻松创建我们自己的自定义方法订购器。
使用@Order 注释进行排序
package pl.codeleak.samples.junit5.basics;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class TestExecutionOrderWithOrderAnnotation {
@Order(1)
@Test
void aTest() {}
@Order(2)
@Test
void bTest() {}
@Order(3)
@Test
void cTest() {}
}
字母数字排序
@TestMethodOrder(MethodOrderer.Alphanumeric.class)
class AlphanumericTestExecutionOrder {
@Test
void aTest() {}
@Test
void bTest() {}
@Test
void cTest() {}
}
随机排序
如果想确保方法的执行顺序在构建过程中不是确定的,那么随机排序就很有用:
@TestMethodOrder(MethodOrderer.Random.class)
class AlphanumericTestExecutionOrder {
@Test
void aTest() {}
@Test
void bTest() {}
@Test
void cTest() {}
}
随机方法排序器使用System.nanoTime() 作为种子,但它可以通过junit.jupiter.execution.order.random.seed 配置属性来改变。这个属性的值应该返回任何可以使用Long.valueOf(String) 转换的String 。
配置种子的一种方法是在junit-platform.properties 配置文件中提供配置属性:
junit.jupiter.execution.order.random.seed=42
自定义排序
创建一个自定义方法排序器可以通过实现org.junit.jupiter.api.MethodOrderer 接口并将其作为参数提供给@TestMethodOrder 。
下面的例子是一个方法排序器,它根据方法的名称长度进行排序:
class MethodLengthOrderer implements MethodOrderer {
private Comparator<MethodDescriptor> comparator =
Comparator.comparingInt(methodDescriptor -> methodDescriptor.getMethod().getName().length());
@Override
public void orderMethods(MethodOrdererContext context) {
context.getMethodDescriptors().sort(comparator);
}
}
以及用途:
@TestMethodOrder(MethodLengthOrderer.class)
class CustomTestExecutionOrder {
@Test
void aTest() {}
@Test
void abTest() {}
@Test
void abcTest() {}
}
总结
在JUnit 5中,有一种调整测试执行顺序的方法在某些情况下很有用,我很高兴看到这个功能。我相信在大多数情况下,内置的方法排序器已经足够了。如果不是,有一个简单的方法来实现一个自定义的。
在GitHub上可以找到本文中使用的例子(还有很多):https://github.com/kolorobot/junit5-samples/tree/master/junit5-basics