Flutter Testing
Flutter Testing
Section titled “Flutter Testing”Ce guide couvre les différents types de tests disponibles en Flutter, des tests unitaires aux tests d’intégration, en passant par les mocks et les tests de rendu.
Tests automatisés
Section titled “Tests automatisés”Flutter offre un écosystème complet pour tester vos applications à différents niveaux :
- Tests unitaires : pour tester la logique métier
- Tests de widgets : pour tester l’interface utilisateur
- Tests d’intégration : pour tester l’application complète
- Tests de couverture : pour mesurer la qualité des tests
- Golden tests : pour tester le rendu visuel
Tests unitaires
Section titled “Tests unitaires”Configuration de base
Section titled “Configuration de base”Flutter intègre directement le support des tests avec le package flutter_test qui étend le package Dart test.
import 'package:test/test.dart';
void main() { test('String.split() splits the string on the delimiter', () { var string = 'foo,bar,baz'; expect(string.split(','), ['foo', 'bar', 'baz']); });
test('String.trim() removes surrounding whitespace', () { var string = ' foo '; expect(string.trim(), 'foo'); });}Packages de test
Section titled “Packages de test”- Dart : Package test
- Flutter : Le SDK Flutter intègre le package flutter_test
Mocking
Section titled “Mocking”Le mocking permet de simuler des dépendances externes pour isoler le code testé.
Choix de la librairie
Section titled “Choix de la librairie”Il existe deux principales librairies de mocking :
Mockito
Section titled “Mockito”La plus ancienne, développée chez Google. Depuis le passage au null safety, elle est moins pratique à utiliser et nécessite de la génération de code.
Mocktail
Section titled “Mocktail”Développé par le créateur du package Bloc, reprend les principes de Mockito en les préservant dans une version null safe plus pratique.
Utilisation de Mocktail
Section titled “Utilisation de Mocktail”Création de mocks
Section titled “Création de mocks”class MockBookService extends Mock implements BookService {}Définition du comportement
Section titled “Définition du comportement”final service = MockService();
// Définir le comportement quand la méthode [service.loadAll] est appeléewhen(() => service.loadAll()) .thenAnswer((_) => Future.value([fakeBook1, fakeBook2]));
// Définir le comportement pour [service.loadBook] avec n'importe quel IDwhen(() => service.loadBook(id: any(named: 'id'))) .thenAnswer((_) => Future.value(fakeBook));Vérification des interactions
Section titled “Vérification des interactions”verify(() => service.loadBook(id: any(named: 'id'))).called(1);Widget Testing avec WidgetTester
Section titled “Widget Testing avec WidgetTester”WidgetTester permet de manipuler “virtuellement” un widget afin de vérifier son comportement dans un environnement de test.
Capacités du WidgetTester
Section titled “Capacités du WidgetTester”Avec ce widget, il est possible de :
-
Rechercher des widgets enfants (voir documentation) :
find.text()find.byKey()find.byType()find.byIcon()find.widgetWithIcon()- Et bien d’autres…
-
Interagir avec l’interface :
tester.tap(...)pour toucher des boutonstester.enterText(...)pour saisir du texte
Exemple complet
Section titled “Exemple complet”import 'package:flutter/material.dart';import 'package:flutter_test/flutter_test.dart';import 'package:my_app/main.dart';
void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized(); await binding.setSurfaceSize(const Size(420, 720));
// Construire l'application et déclencher un frame await tester.pumpWidget(const MyApp());
// Vérifier que le compteur commence à 0 expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing);
// Appuyer sur l'icône '+' et déclencher un frame await tester.tap(find.byIcon(Icons.add)); await tester.pump();
// Vérifier que le compteur a été incrémenté expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); });}Test Coverage (Couverture de tests)
Section titled “Test Coverage (Couverture de tests)”Flutter permet de générer des informations de couverture de test pour mesurer quelle partie de votre code est testée.
Génération de la couverture
Section titled “Génération de la couverture”En ligne de commande :
flutter test --coverageDans IntelliJ/Android Studio : Utiliser l’option “Run … with Coverage”
Analyse des résultats
Section titled “Analyse des résultats”Un fichier lcov.info est créé dans ./coverage/lcov.info.
Pour lire ce fichier et générer un rapport HTML :
-
Installer genhtml
-
Générer le rapport :
genhtml coverage/lcov.info -o coverageopen coverage/index.htmlLe rapport généré ressemble à ceci :

Golden Tests
Section titled “Golden Tests”Les golden tests permettent de tester le rendu graphique de widgets à partir d’images de référence. Ils sont particulièrement utiles pour détecter les changements visuels non intentionnels.
Package Alchemist
Section titled “Package Alchemist”Alchemist est un package qui simplifie la création de golden tests.

Avantages des Golden Tests
Section titled “Avantages des Golden Tests”- Détection automatique des régressions visuelles
- Validation du rendu sur différentes plateformes
- Documentation visuelle du comportement attendu
Tests d’intégration
Section titled “Tests d’intégration”Les tests d’intégration permettent de tester l’application de manière “globale”, en simulant les interactions utilisateur réelles.
Configuration
Section titled “Configuration”Flutter SDK intègre un package integration_test :
dev_dependencies: integration_test: sdk: flutterUtilisation
Section titled “Utilisation”Les tests d’intégration permettent de :
- Tester les flux utilisateur complets
- Valider l’intégration entre les différentes parties de l’application
- Tester sur de vrais appareils ou émulateurs
Consultez la documentation officielle pour plus de détails.
Bonnes pratiques de test
Section titled “Bonnes pratiques de test”1. Séparation des responsabilités
Section titled “1. Séparation des responsabilités”L’utilisation de setState rend difficile la séparation Vue/Logique et par conséquent la testabilité. Privilégiez les patterns de state management comme Provider, Bloc, ou Riverpod.
2. Structure des tests
Section titled “2. Structure des tests”- Organisez vos tests en groupes logiques
- Nommez clairement vos tests pour décrire le comportement testé
- Utilisez des setup et teardown appropriés
3. Couverture de test
Section titled “3. Couverture de test”- Visez une couverture élevée mais sensée
- Concentrez-vous sur la logique métier critique
- N’oubliez pas les cas d’erreur et les edge cases
4. Mocking intelligent
Section titled “4. Mocking intelligent”- Mockez uniquement les dépendances externes
- Préférez les vrais objets quand c’est possible
- Validez les interactions importantes avec vos mocks
5. Tests de widgets
Section titled “5. Tests de widgets”- Testez le comportement utilisateur, pas l’implémentation
- Utilisez des keys pour identifier les widgets critiques
- Testez les différents états de vos widgets