Kotlin 测试入门:从单元测试到端到端测试
高质量的代码库离不开自动化测试。Kotlin 作为一门面向 JVM 的现代语言,为开发者提供了丰富的工具集,用于创建可靠的测试。在本文中,我们将针对 Kotlin,层层剖析测试金字塔的三个层级:单元测试、集成测试和端到端测试。你将学习如何使用 JUnit 5、MockK、Ktor Client 和 Selenium 等流行框架在 Kotlin 中编写高效的测试。
1. Kotlin 中的单元测试:稳定性的基石
单元测试用于验证单个函数、类或方法在隔离外部依赖情况下的运行情况。在 Kotlin 中,最常用的是 JUnit 5,配合模拟库 MockK 一起使用。
1.1. 项目设置
将依赖添加到 build.gradle.kts 文件中:
dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testImplementation("io.mockk:mockk:1.13.8")}1.2. 使用 MockK 的单元测试示例
假设我们有一个依赖于仓库的 UserService:
class UserService(private val repository: UserRepository) { fun getUserName(id: Long): String { val user = repository.findById(id) return user?.name ?: "Unknown" }}使用 MockK 进行测试:
import io.mockk.everyimport io.mockk.mockkimport org.junit.jupiter.api.Testimport kotlin.test.assertEquals
class UserServiceTest { @Test fun `当用户存在时返回用户名`() { val mockRepo = mockk<UserRepository>() every { mockRepo.findById(1L) } returns User(1L, "Alice") val service = UserService(mockRepo)
val result = service.getUserName(1L)
assertEquals("Alice", result) }}1.3. 单元测试最佳实践
- 隔离依赖 — 对所有外部调用(数据库、API)使用模拟对象。
- 测试边界情况:空值、空字符串、负数。
- 使用清晰的测试名称 — 应能描述场景和预期结果。
- 遵循 AAA 原则:安排(Arrange)、执行(Act)、断言(Assert)。
2. Kotlin 中的集成测试:验证交互
集成测试用于验证多个系统组件如何协同工作。在 Kotlin 中,这可能是使用 Ktor Client 测试 REST API,或通过 Exposed 检查数据库操作。
2.1. 使用 Ktor 测试 REST API
创建一个简单的 Ktor 服务器并进行测试:
// 服务器fun Application.module() { routing { get("/hello") { call.respondText("Hello, Kotlin!") } }}
// 测试class ApiTest { @Test fun `测试 hello 端点`() = testApplication { application { module() } val response = client.get("/hello") assertEquals(HttpStatusCode.OK, response.status) assertEquals("Hello, Kotlin!", response.bodyAsText()) }}2.2. 使用测试数据库
对于集成测试,使用 H2(内存数据库)或用于 PostgreSQL 的 Testcontainers:
@Testfun `测试用户创建`() { withTestDatabase { val user = User.new { name = "Bob" email = "bob@test.com" } assertEquals("Bob", user.name) assertNotNull(user.id) }}
private fun withTestDatabase(block: () -> Unit) { Database.connect("jdbc:h2:mem: