引言:为什么使用 Docker 进行集成测试?
在使用 Kotlin 开发现代应用(尤其是微服务)时,验证系统组件之间及与外部依赖(数据库、消息队列、缓存)的交互至关重要。单元测试虽然能隔离代码,但无法保证应用在真实环境中的正确运行。
使用 Docker 进行集成测试解决了这一问题。Docker 允许在测试运行前启动包含必要服务(PostgreSQL、Redis、Kafka)的独立容器,并在测试完成后自动销毁它们。这提供了以下优势:
- 可复现性:测试始终在相同的环境中运行。
- 隔离性:容器不会影响本地开发环境。
- 速度:容器在数秒内即可启动,而非数分钟。
在本篇文章中,我们将介绍如何使用 Docker、Testcontainers 库以及 Docker Compose 为 Kotlin 应用设置集成测试。您将获得现成的代码示例和最佳实践。
1. 为集成测试配置 Kotlin 项目
1.1. build.gradle.kts 中的依赖
首先,在您的 build.gradle.kts 文件中添加必要的依赖。我们将使用 JUnit 5、Testcontainers 以及 PostgreSQL 驱动:
dependencies { // 主应用依赖 implementation("org.jetbrains.kotlin:kotlin-stdlib") implementation("org.postgresql:postgresql:42.7.1")
// 测试依赖 testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") testImplementation("org.testcontainers:testcontainers:1.19.3") testImplementation("org.testcontainers:postgresql:1.19.3") testImplementation("org.testcontainers:junit-jupiter:1.19.3")}
tasks.test { useJUnitPlatform()}1.2. 测试类的基本结构
让我们创建一个简单的集成测试类,它将启动一个 PostgreSQL 容器:
import org.junit.jupiter.api.Testimport org.testcontainers.containers.PostgreSQLContainerimport org.testcontainers.junit.jupiter.Containerimport org.testcontainers.junit.jupiter.Testcontainersimport java.sql.DriverManager
@Testcontainersclass UserRepositoryIntegrationTest {
companion object { @Container val postgres = PostgreSQLContainer<Nothing>("postgres:15-alpine") .withDatabaseName("testdb") .withUsername("test") .withPassword("test") }
@Test fun `should connect to database and execute query`() { val jdbcUrl = postgres.jdbcUrl val username = postgres.username val password = postgres.password
val connection = DriverManager.getConnection(jdbcUrl, username, password) val statement = connection.createStatement()
statement.execute("CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name VARCHAR(100))") statement.execute("INSERT INTO users (name) VALUES ('Alice')")
val resultSet = statement.executeQuery("SELECT COUNT(*) FROM users") resultSet.next() val count = resultSet.getInt(1)
assert(count == 1) println("Test passed: found $count users") }}请注意:@Testcontainers 注解会自动管理容器的生命周期。它会在该类中所有测试开始前启动容器,并在测试完成后停止容器。
2. 使用多容器进行测试(Docker Compose)
在实际项目中,通常需要同时使用多个服务:数据库、Redis、Kafka。Testcontainers 支持 Docker Compose,允许您在一个文件中描述整个基础设施。