Introduction aux tests en Kotlin : des modules à l'expérience utilisateur
Kotlin est un langage moderne activement utilisé pour le développement d'applications serveur (Ktor, Spring Boot), d'applications Android et de projets multiplateformes. Cependant, la qualité du code est impossible sans des tests compétents. Dans cet article, nous allons aborder trois niveaux clés : les tests unit (unitaires), integration (d'intégration) et e2e (de bout en bout). Vous découvrirez quels outils utiliser, comment écrire des tests en Kotlin et comment construire une stratégie fiable pour vérifier votre application.
1. Tests unitaires en Kotlin : le fondement de la stabilité
Les tests unitaires vérifient des fonctions, classes ou méthodes individuelles isolées de leurs dépendances externes. En Kotlin, on utilise le plus souvent JUnit 5 et MockK.
Outils et configuration
Ajoutez les dépendances dans build.gradle.kts :
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testImplementation("io.mockk:mockk:1.13.8")
}
Exemple de test unitaire avec MockK
Supposons que nous ayons un service qui dépend d'un repository :
class UserService(private val repo: UserRepository) {
fun getUserName(id: Int): String {
val user = repo.findById(id)
return user?.name ?: "Unknown"
}
}
Test avec MockK :
import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class UserServiceTest {
@Test
fun `getUserName returns name when user exists`() {
val mockRepo = mockk<UserRepository>()
every { mockRepo.findById(1) } returns User(1, "Alice")
val service = UserService(mockRepo)
assertEquals("Alice", service.getUserName(1))
}
}
Bonnes pratiques pour les tests unitaires
- Un test = une vérification (utilisez
assertà bon escient). - Isolez les dépendances : utilisez des mocks (MockK) ou des stubs.
- Nommez les tests de manière claire :
shouldReturnX_whenY. - Testez les cas limites : null, listes vides, exceptions.
2. Tests d'intégration : vérification de l'interconnexion des composants
Les tests d'intégration vérifient comment les composants réels fonctionnent ensemble : base de données, API, système de fichiers. En Kotlin, il est pratique d'utiliser Testcontainers et Ktor Client (si vous développez un serveur).
Exemple : test d'un repository avec PostgreSQL
Ajoutez Testcontainers et exposed (bibliothèque pour travailler avec la base de données) :
dependencies {
testImplementation("org.testcontainers:postgresql:1.19.3")
implementation("org.jetbrains.exposed:exposed:0.44.1")
}
Test pour UserRepository :
import org.junit.jupiter.api.*
import org.testcontainers.containers.PostgreSQLContainer
import org.testcontainers.junit.jupiter.Container
import org.testcontainers.junit.jupiter.Testcontainers
import org.jetbrains.exposed.sql.*
@Testcontainers
class UserRepositoryIntegrationTest {
@Container
val postgres = PostgreSQLContainer<Nothing>("postgres:15").apply {
withDatabaseName("testdb")
withUsername("test")
withPassword("test")
}
private lateinit var repo: UserRepository
@BeforeEach
fun setUp() {
Database.connect(postgres.jdbcUrl, driver = "org.postgresql.Driver", user = postgres.username, password = postgres.password)
transaction { SchemaUtils.create(Users) }
repo = UserRepository()
}
@Test
fun `save and find user by id`() {
val user = User(1, "Bob")
repo.save(user)
val found = repo.findById(1)
assertEquals("Bob", found?.name)
}
@AfterEa
```