Junit5速查
官方文档:https://junit.org/junit5/docs/current/user-guide/#overview
- 注解速查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16注解 描述
@Test 表示方法是一种测试方法。 与JUnit 4的@Test注解不同,此注释不会声明任何属性。
@ParameterizedTest 表示方法是参数化测试
@RepeatedTest 表示方法是重复测试模板
@TestFactory 表示方法是动态测试的测试工程
@TestInstance 用于配置测试实例生命周期
@TestTemplate 表示方法是为多次调用的测试用例的模板
@DisplayName 为测试类或者测试方法自定义一个名称
@BeforeEach 表示方法在每个测试方法运行前都会运行
@AfterEach 表示方法在每个测试方法运行之后都会运行
@BeforeAll 表示方法在所有测试方法之前运行
@AfterAll 表示方法在所有测试方法之后运行
@Nested 表示带注解的类是嵌套的非静态测试类,@BeforeAll和@AfterAll方法不能直接在@Nested测试类中使用,除非修改测试实例生命周期。
@Tag 用于在类或方法级别声明用于过滤测试的标记
@Disabled 用于禁用测试类或测试方法
@ExtendWith 用于注册自定义扩展,该注解可以继承
断言速查
1
2
3
4
5
6
7
8
9断言 描述
assertEquals 断言预期值和实际值相等
assertAll 分组断言,执行其中包含的所有断言
assertArrayEquals 断言预期数组和实际数组相等
assertFalse 断言条件为假
assertNotNull 断言不为空
assertSame 断言两个对象相等
assertTimeout 断言超时
fail 使单元测试失败常用断言的使用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96import static java.time.Duration.ofMillis;
import static java.time.Duration.ofMinutes;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class Assert {
@Test
void standardAssertions() {
assertEquals(2, 2);
assertEquals(4, 4, "error message");
assertTrue(2 == 2, () -> "error message");
}
@Test
void groupedAssertions() {
//分组断言,执行分组中所有断言,分组中任何一个断言错误都会一起报告
assertAll("person",
() -> assertEquals("John", "John"),
() -> assertEquals("Doe", "Doe")
);
}
@Test
void dependentAssertions() {
//分组断言
assertAll("properties",
() -> {
// 在代码块中,如果断言失败,后面的代码将不会运行
String firstName = "John";
assertNotNull(firstName);
// 只有前一个断言通过才会运行
assertAll("first name",
() -> assertTrue(firstName.startsWith("J")),
() -> assertTrue(firstName.endsWith("n"))
);
},
() -> {
// 分组断言,不会受到first Name代码块的影响,所以即使上面的断言执行失败,这里的依旧会执行
String lastName = "Doe";
assertNotNull(lastName);
// 只有前一个断言通过才会运行
assertAll("last name",
() -> assertTrue(lastName.startsWith("D")),
() -> assertTrue(lastName.endsWith("e"))
);
}
);
}
@Test
void exceptionTesting() {
//断言异常,抛出指定的异常,测试才会通过
Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("a message");
});
assertEquals("a message", exception.getMessage());
}
@Test
void timeoutNotExceeded() {
// 断言超时
assertTimeout(ofMinutes(2), () -> {
// 完成任务小于2分钟时,测试通过。
});
}
@Test
void timeoutNotExceededWithResult() {
// 断言成功并返回结果
String actualResult = assertTimeout(ofMinutes(2), () -> {
return "result";
});
assertEquals("result", actualResult);
}
@Test
void timeoutExceeded() {
// 断言超时,会在任务执行完毕后才返回,也就是1000毫秒后返回结果
assertTimeout(ofMillis(10), () -> {
// 执行任务花费时间1000毫秒
Thread.sleep(1000);
});
}
@Test
void timeoutExceededWithPreemptiveTermination() {
// 断言超时,如果在10毫秒内任务没有执行完毕,会立即返回断言失败,不会等到1000毫秒后
assertTimeoutPreemptively(ofMillis(10), () -> {
Thread.sleep(1000);
});
}
}假设
1
2
3
4方法 描述
assumeFalse 假设为false时才会执行,如果为true,那么将会直接停止执行
assumeTrue 假设为true时才会执行,如果为false,那么将会直接停止执行
assumingThat assumingThat接受一个函数式接口Executable,假设为true时执行,将会执行Executable,否则不会执行Executable。
1 | // 演示demo |
- 条件测试
1
2
3
4
5
6
7
8
9
10通过 @EnabledOnOs 和 @DisabledOnOs 注解来在指定的操作系统上运行或者关闭测试。
JAVA运行环境条件
通过 @EnabledOnJre 和 @DisabledOnJre 注解在指定的JAVA环境(jre)下运行或者关闭测试。
系统属性条件
根据 JVM 系统属性来开启或者关闭测试,通过@EnabledIfSystemProperty 和 @DisabledIfSystemProperty 注解来实现。这两个注解都拥有named和matches两个参数。named为 JVM 系统参数名称,matches接受一个正则表达式,用于匹配指定参数的值。
环境变量条件
根据系统环境变量来开启或者关闭测试,通@EnabledIfEnvironmentVariable和@DisabledIfEnvironmentVariable 注解来实现,都拥有named和matches两个参数。named为环境变量参数名称,matches接受一个正则表达式,用于匹配指定参数的值。
1 | // 演示demo |
tag标签
1
2
3
4
5
6
7
8
9
10
11@Test
@Tag("tag1")
void tag1() {
System.out.println("Tag1 Test");
}
@Test
@Tag("tag2")
void tag2() {
System.out.println("Tag2 test");
}idea中tag标签可以在run configuration中指定
tag experssion可以参考下图
重复测试
1
2
3
4
5
6
7
8
9
10//自定义重复测试的显示名称
@RepeatedTest(value=10,name="{displayName}-->{currentRepetition}/{totalRepetitions}")
@DisplayName("repeatTest")
void repeatedTest(TestInfo testInfo, RepetitionInfo repetitionInfo) {
//我们可以通过TestInfo在测试中获取测试的相关信息,比如输出自定义的测试名
System.out.println(testInfo.getDisplayName());
//输出当前重复次数
System.out.println("currentRepetition:"+repetitionInfo.getCurrentRepetition());
}
参数化测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27@ValueSource允许指定单个文字值数组,并且只能用于为每个参数化测试调用提供单个参数。@ValueSource支持下面几种文字值:
short
byte
int
long
float
double
char
java.lang.String
java.lang.Class
@EnumSource
@EnumSource提供了一种使用 Enum 常量的便捷方法。注释提供了一个可选 names 参数,允许指定应使用哪些常量。如果省略,将使用所有常量。
@MethodSource
@MethodSource允许引用测试类或外部类的一个或多个工厂方法。这个方法必须是static的(除非修改测试类生命周期为@TestInstance(Lifecycle.PER_CLASS)),返回值必须是一个Stream、Iterable、Iterator 或者参数数组。并且这些方法不能有参数。外部类的方法则必须是static的。
@CsvSource
@CsvSource允许将参数列表定义为以逗号分隔的值(即String类型)。@CsvSource使用单引号'作为引号字符。空的引用值''会被解释成空的的 String 类型; 而完全空值被解释为 null。
输入 输出
@CsvSource({ "shi, yan" }) "shi","yan"
@CsvSource({ "shi, 'yan,lou'" }) "shi","yanlou"
@CsvSource({ "shi, ''" }) "shi",""
@CsvSource({ "shi, " }) "shi",null
@ArgumentsSource @ArgumentsSource可用于指定自定义,可重用 ArgumentsProvider。自定义时需要实现ArgumentsProvider接口,并且必须将实现声明为 public 类或 static 嵌套类。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34// 演示demo
@ParameterizedTest
@ValueSource(strings= {"shi","yan","lou"})
void parameter(String args) {
System.out.println(args);
}
@ParameterizedTest
//使用names制定需要的枚举常量
@EnumSource(value = TimeUnit.class, names = { "DAYS", "HOURS" })
void enumSource(TimeUnit timeUnit) {
System.out.println(timeUnit.toString());
}
@ParameterizedTest
@CsvSource({ "shi, 1", "yan, 2", "'lou, plus', 3" })
void csvSource(String first, int second) {
System.out.println(first+"---"+second);
}
@ParameterizedTest
@ArgumentsSource(MyArgumentsProvider.class)
void argumentsSource(String argument) {
System.out.print(argument);;
}
static class MyArgumentsProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of("shi-", "yan-", "lou\n").map(Arguments::of);
}
}易忽略点
1
2
3- beforeall和afterall两个方法需要实用static关键词进行定义
- 在junit5中,使用disabled替代了ignore注解,ignore注解已经不生效了
- @ArgumentsSource @ArgumentsSource可用于指定自定义,可重用 ArgumentsProvider。自定义时需要实现ArgumentsProvider接口,并且必须将实现声明为 public 类或 static 嵌套类。