Turbine pour Kotlin : guide complet pour tester vos Flow
1. Qu'est-ce que Turbine et pourquoi l'utiliser ?
La bibliothèque Turbine est un outil moderne pour tester les flux de données asynchrones (Flow) en Kotlin. Développée par Cash App, Turbine résout l'un des problèmes les plus épineux des tests unitaires pour le code asynchrone : la vérification des valeurs émises par un Flow, la gestion des erreurs et la détection de la fin du flux. Contrairement aux approches classiques comme kotlinx-coroutines-test avec une collecte manuelle, Turbine propose une API déclarative et intuitive qui rend vos tests plus lisibles et fiables.
Pourquoi Turbine ? Imaginez que vous développez une ViewModel qui s'abonne à un repository et transforme les données en état UI. Sans Turbine, vous devriez créer manuellement des collecteurs, gérer des jobs et synchroniser les coroutines. Turbine automatise tout cela : elle crée une coroutine virtuelle, collecte toutes les émissions dans une "turbine" (d'où son nom), puis vous permet de vérifier chaque valeur dans l'ordre, en ignorant les états intermédiaires non pertinents. C'est particulièrement utile pour tester des flux de type BehaviourSubject où seul l'état final compte.
Les fonctionnalités principales incluent : la vérification des valeurs émises dans un ordre strict, l'ignorance des valeurs intermédiaires avec skip(), le test des erreurs via awaitError(), la vérification de la fin du flux avec awaitComplete(), ainsi que la compatibilité avec les canaux (Channel) et StateFlow. Turbine s'intègre avec tous les frameworks de test (JUnit, Kotest, Spek) et ne nécessite aucune configuration supplémentaire : ajoutez simplement la dépendance et utilisez testScope.
2. Installation
Pour utiliser Turbine dans votre projet, ajoutez la dépendance suivante dans votre fichier build.gradle.kts (ou build.gradle) :
// build.gradle.kts
dependencies {
// Pour les projets JVM
testImplementation("app.cash.turbine:turbine:1.1.0")
// Si vous utilisez kotlinx-coroutines-test (recommandé)
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
}
// Pour les projets Android (dans le bloc android)
android {
testOptions {
unitTests.isReturnDefaultValues = true
}
}
Si vous utilisez Maven :
<dependency>
<groupId>app.cash.turbine</groupId>
<artifactId>turbine</artifactId>
<version>1.1.0</version>
<scope>test</scope>
</dependency>
Prérequis minimaux : Kotlin 1.9+, kotlinx-coroutines 1.8+. La bibliothèque prend en charge JVM, Android, JS et Native (via Kotlin Multiplatform).
3. Démarrage rapide
Voici un exemple simple : tester un Flow qui émet trois nombres.
import app.cash.turbine.test
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Test
class SimpleTurbineTest {
@Test
fun `test flow émet trois valeurs`() = runTest {
val flow = flowOf(1, 2, 3)
flow.test {
// awaitItem() attend la prochaine émission et la retourne
assertEquals(1, awaitItem())
assertEquals(2, awaitItem())
assertEquals(3, awaitItem())
// awaitComplete() vérifie que le flux se termine sans erreur
awaitComplete()
}
}
}
Exécutez ce test : il passera avec succès. Notez que test est une fonction suspend qui lance la collecte du flux dans une coroutine séparée. Tous les appels à awaitItem() bloquent la coroutine actuelle jusqu'à l'arrivée de l'élément suivant. Si le flux se termine plus tôt que prévu, le test échoue avec un message d'erreur clair.
4. Méthodes et fonctions principales
Aussi dans la bibliothèque
Journalisation pour Swift : bibliothèque SwiftyBeaver
Travailler avec S3 et les stockages cloud en Go : la bibliothèque minio-go
Internationalisation (i18n) en TypeScript : guide complet
Sharp pour JavaScript (Node.js) : guide complet avec exemples
Travailler avec Markdown en Rust : bibliothèques et outils