Kotest Testcontainers Extension
Testcontainers
Testcontainers is a tool for building independent and reusable test environments. It supports container-based testing, so you can programmatically build the same environment as the test environment running on your local machine. Kotest can be used with Testcontainers to manage external resources needed for tests, helping you write more robust and reliable tests.
The main advantages of using Testcontainers are:
- Consistent environment: Provides a consistent environment each time a test runs, making test results predictable.
- Independence: Containerizes external resources so tests do not affect each other.
- Ease of building test environments: Lets you programmatically build and manage test environments with code.
- Support for various containers: Supports various kinds of containers, such as Docker and Kubernetes, so you can build many test scenarios.
The Testcontainers project provides lightweight temporary instances of common databases, Elasticsearch, Kafka, Selenium web browsers, or anything else that can run in a Docker container, making them ideal for use inside tests.
Kotest provides integration with Testcontainers through an additional module that offers several extensions, including special extensions for databases and Kafka and general container support for all supported Docker images.
Adding the Dependency
To use it, add the following dependency to your Gradle build file.
dependencies {
testImplementation("io.kotest.extensions:kotest-extensions-testcontainers:${kotestVersion}")
}
Note: The group ID
io.kotest.extensionsdiffers from the main Kotest group ID,io.kotest.
For Maven projects, add the dependency as follows:
<dependency>
<groupId>io.kotest.extensions</groupId>
<artifactId>kotest-extensions-testcontainers</artifactId>
<version>${kotest.version}</version>
<scope>test</scope>
</dependency>
Databases
Using Testcontainers in Kotest is straightforward. Start the required container using the Testcontainers library inside the test code, run the test, and then clean up the container afterward.
For example, when performing database integration tests, it is common to start the database container at the beginning of the test and stop it when the test ends.
For this, Kotest lets you use beforeTest and afterTest to perform required work before and after test execution.
The following is example code using Kotest and Testcontainers together:
import io.kotest.core.spec.style.FreeSpec
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers
@Testcontainers
class PostgreSqlTest : FreeSpec() {
companion object {
@Container
val postgresContainer: PostgreSQLContainer<Nothing> = PostgreSQLContainer<Nothing>()
.withDatabaseName("test")
.withUsername("test")
.withPassword("test")
.withExposedPorts(5432)
}
override fun beforeTest(testCase: TestCase) {
postgresContainer.start()
System.setProperty("DB_URL", postgresContainer.jdbcUrl)
System.setProperty("DB_USERNAME", postgresContainer.username)
System.setProperty("DB_PASSWORD", postgresContainer.password)
}
override fun afterTest(testCase: TestCase, result: TestResult) {
postgresContainer.stop()
}
init {
"Database test" {
// write database test code
}
}
}
In the code above, a PostgreSQL container is used to perform database testing. The @Testcontainers annotation enables Testcontainers, and the @Container annotation defines the container. Then beforeTest and afterTest are overridden to start and stop the container before and after test execution.