使用@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
,然后使用@Order
注解就可以指定一个类中方法执行的优先级,其中,数字越小,代表优先级越高。
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class OrderedExecutionTest {
@Test
@Order(2)
public void testTwo() {
System.out.println("Executing testTwo");
assertEquals(4, 2 + 2);
}
@Test
@Order(1)
public void testOne() {
System.out.println("Executing testOne");
assertEquals(4, 2 + 2);
}
@Test
@Order(3)
public void testThree() {
System.out.println("Executing testThree");
assertEquals(4, 2 + 2);
}
}
对于日益增长的测试用例,在不好管理的情况下,JUnit5支持内部类的测试注解。
public class NestedTest {
@Nested
@DisplayName("Testing division functionality")
class DivisionTests {
@Test
public void shouldDivideByTwo() {
assertEquals(4, 8 / 2);
}
@Test
public void shouldThrowExceptionForDivideByZero() {
assertThrows(ArithmeticException.class, () -> {
int result = 8 / 0;
});
}
}
@Nested
@DisplayName("Testing addition functionality")
class AdditionTests {
@Test
public void shouldAddTwo() {
assertEquals(4, 2 + 2);
}
@Test
public void shouldAddZero() {
assertEquals(2, 2 + 0);
}
}
}
可以在测试类的构造参数,或者测试方法支持参数注入。有内建的常用注解参数,也可以自定义。
//对于方法的这几个参数都是内建的
@RepeatedTest(5)
public void testMethodName(TestInfo testInfo, TestReporter testReporter, RepetitionInfo repetitionInfo) {
System.out.println(testInfo.getTestMethod().get().getName());
testReporter.publishEntry("secretMessage", "JUnit 5");
System.out.println(repetitionInfo.getCurrentRepetition() + " from " + repetitionInfo.getTotalRepetitions());
}
对于自定的,需要实现接口ParameterResolver
,使用的时候使用ExtendWith
注解将实现类注入。
public class RandomUUIDParameterResolver implements ParameterResolver {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface RandomUUID {
}
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
return parameterContext.isAnnotated(RandomUUID.class);
}
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
return UUID.randomUUID().toString();
}
}
//使用
@ExtendWith(RandomUUIDParameterResolver.class)
public class ParameterInjectionTest {
@RepeatedTest(5)
public void testUUIDInjection(@RandomUUID String uuid) {
System.out.println("Random UUID: " + uuid);
}
}
从5.3版本开始支持并行测试,作为一个实验特性。可以通过在maven插件中配置属性,或者使用junit-platform.properties
在src/test/resources
路径下。
//属性
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
//maven配置中
maven-surefire-plugin
2.22.2
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
测试执行的时候,可以根据某些条件,选择那些测试方法不执行。可以是比如操作系统、或者不同环境之类的各种条件,同样的,有内置的部分,也可以自定义条件。
@Test
@DisabledOnOs(OS.LINUX)
public void disabledOnLinux() {
assertEquals(42, 40 + 2);
}
@Test
@DisabledIfEnvironmentVariable(named = "FLAKY_TESTS", matches = "false")
public void disableFlakyTest() {
assertEquals(42, 40 + 2);
}
自定义的,实现ExecutionCondition
接口即可:
@Test
@DisabledOnMidnight
public void disabledOnMidNight() {
assertEquals(42, 40 + 2);
}
//自定义的实现
public class DisabledOnMidnightCondition implements ExecutionCondition {
private static final ConditionEvaluationResult ENABLED_BY_DEFAULT =
enabled("@DisabledOnMidnight is not present");
private static final ConditionEvaluationResult ENABLED_DURING_DAYTIME =
enabled("Test is enabled during daytime");
private static final ConditionEvaluationResult DISABLED_ON_MIDNIGHT =
disabled("Disabled as it is around midnight");
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisabledOnMidnightCondition.class)
public @interface DisabledOnMidnight {
}
@Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
Optional optional = findAnnotation(context.getElement(), DisabledOnMidnight.class);
if (optional.isPresent()) {
LocalDateTime now = LocalDateTime.now();
if (now.getHour() == 23 || now.getHour() <= 1) {
return DISABLED_ON_MIDNIGHT;
} else {
return ENABLED_DURING_DAYTIME;
}
}
return ENABLED_BY_DEFAULT;
}
}