6.1.4 使用 Maven 测试 Kotlin 项目
原文链接: https://kotlinlang.org/docs/jvm-test-maven.html
6.1.4 使用 Maven 测试 Kotlin 项目
Kotlin 与 Maven 生态无缝集成,让你可以使用业界标准工具来验证后端应用。在本指南中,你将学习如何用 JUnit 创建测试,并使用 Maven 插件运行单元测试和集成测试。
提示: 关于如何配置 Maven 项目以同时使用 Kotlin 和 Java 的详细指南,请参阅 。
用 JUnit 创建测试
JUnit 是 Kotlin 后端开发的标准测试框架。虽然 Kotlin 支持多个 JUnit 版本,但大多数现代项目应使用 JUnit 6。
要用 JUnit 在 Kotlin 中创建测试,请使用来自 kotlin.test 或 JUnit 包的 @Test 注解。
添加依赖
kotlin-test 库是最简单的入门方式。它提供了一组通用的断言,并会自动引入必要的 JUnit 构件。
JUnit 5 及更高版本
对于所有新项目,请使用 kotlin-test-junit5 构件。它提供对 JUnit 的完整支持,包括嵌套测试和并行执行等特性。Kotlin/JVM 支持最新的稳定 JUnit 版本,即 JUnit 6。
按如下方式更新你的 pom.xml 文件:
1
2
3
4
5
6
7
8
| <dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<version>2.4.20</version>
<scope>test</scope>
</dependency>
</dependencies>
|
注意: 尽管名字如此,kotlin-test-junit5 支持所有最新的 JUnit 版本,包括 JUnit 6。
JUnit 4
如果你想使用较早版本的 JUnit(例如用于遗留项目),请使用基于 JUnit 4 的 kotlin-test-junit 构件:
1
2
3
4
5
6
7
8
9
|
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit</artifactId>
<version>2.4.20</version>
<scope>test</scope>
</dependency>
</dependencies>
|
提示: 关于使用 JUnit 进行测试的详细指南和示例项目,请参阅用 Kotlin 测试 Java 代码教程。
编写单元测试
单元测试用于验证代码中相互隔离的部分,例如单个函数或类。按约定,单元测试以 *Test 后缀命名。例如:
1
2
3
4
5
6
7
8
9
10
11
| import kotlin.test.Test
import kotlin.test.assertEquals
class OrderServiceTest {
@Test
fun `calculate total should sum item prices`() {
val service = OrderService()
val result = service.calculateTotal(listOf(10.0, 25.0))
assertEquals(35.0, result)
}
}
|
编写集成测试
集成测试用于验证组件之间的交互,例如服务与数据库之间。按约定,集成测试以 *IT 后缀命名。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| import kotlin.test.Test
import kotlin.test.assertNotNull
class UserRepositoryIT {
@Test
fun saveFindUser() {
// 与数据库或服务集成的示例
val repository = UserRepository()
repository.save(User("KotlinUser"))
val user = repository.findByName("KotlinUser")
assertNotNull(user)
}
}
|
运行测试
在 Maven 项目中,测试执行通常分为两个插件:Surefire 和 Failsafe,以保证构建生命周期清晰。
使用 Surefire 插件
Surefire 插件负责单元测试。它会运行所有遵循 *Test 命名模式的 Kotlin 和 Java 测试。
默认情况下,它在构建生命周期的 test 阶段执行,并在测试失败时立即让构建失败。
1
2
3
4
5
| <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.5</version>
</plugin>
|
要只运行单元测试,请使用以下命令:
使用 Failsafe 插件
Failsafe 插件负责集成测试。它会运行所有遵循 *IT 命名模式的 Kotlin 和 Java 测试。
与 Surefire 不同,Failsafe 允许构建在 integration-test 阶段有测试失败时继续执行,从而让 post-integration-test 阶段的任务(例如停止 Docker 容器)得以运行。如果存在测试失败,构建最终会在 verify 阶段失败。
1
2
3
4
5
6
7
8
9
10
11
12
13
| <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.5.5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
|
要同时运行单元测试和集成测试,请使用以下命令:
获取详细的失败信息
Kotlin 的 Power-assert 编译器插件会生成详细的失败信息,在断言中显示中间值,从而在控制台输出中给出完整的关系图。
- 要启用 Power-assert,请把以下配置添加到项目的
pom.xml 中:
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
| <properties>
<kotlin.version>2.4.20</kotlin.version>
<kotlin.compiler.jdkRelease>17</kotlin.compiler.jdkRelease>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>compile</id>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<compilerPlugins>
<plugin>power-assert</plugin>
</compilerPlugins>
<pluginOptions>
<option>power-assert:function=kotlin.test.assertEquals</option>
<option>power-assert:function=kotlin.test.assertTrue</option>
</pluginOptions>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-power-assert</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
|
kotlin-maven-power-assert 配置
- 在
<properties> 部分,设置 Kotlin 版本和目标 JDK 发行版本,例如 JDK 17。 - 在
<dependencies> 部分,添加 kotlin-test-junit5 以运行测试。 - 在
<build><plugins> 部分,配置带 power-assert 编译器插件的 kotlin-maven-plugin。在 <pluginOptions> 下列出你想转换的断言函数,并添加 Power-assert 插件依赖。
- 在
src/test/kotlin 目录中创建测试文件 UserProfileBackendTest.kt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import kotlin.test.Test
import kotlin.test.assertEquals
class UserProfileBackendTest {
data class UserProfile(val id: Long, val email: String)
@Test
fun `verify backend entity mapping matches`() {
// 定义期望的对象状态
val expectedRecord = UserProfile(id = 451L, email = "admin-dev@company.internal")
// 模拟一个不匹配的后端响应
val actualRecord = UserProfile(id = 451L, email = "admin-prod@company.com")
// 使用标准的 kotlin.test 断言
assertEquals(expectedRecord, actualRecord, "Profile configurations out of sync")
}
}
|
- 运行测试并查看输出:
控制台会显示完整的 Power-assert 关系图,展示表达式中每个位置上期望值与实际值的差异:
1
2
3
4
5
| Profile configurations out of sync
assertEquals(expectedRecord, actualRecord, "Profile configurations out of sync")
| |
| UserProfile(id=451, email=admin-prod@company.com)
UserProfile(id=451, email=admin-dev@company.internal)
|
探索其他测试框架
除 JUnit 之外,你还可以使用其他流行框架,让 Kotlin 测试更符合语言习惯、更易读:
| 库 | 说明 |
| AssertJ | 支持链式断言的流式断言库。 |
| Mockito-Kotlin | Mockito 的 Kotlin 封装,提供辅助函数以及与 Kotlin 类型系统更好的集成。 |
| MockK | 原生 Kotlin 模拟库,支持 Kotlin 特有特性,包括协程和扩展函数。 |
| Kotest | Kotlin 的断言库,提供多种断言风格和丰富的匹配器支持。 |
| Strikt | Kotlin 的断言库,支持类型安全断言和数据类。 |
接下来学什么