7.4 KiB
Tests Unitaires - Progression
Date: 2026-03-14 Objectif: Implémenter tests unitaires pour 64 use cases Statut: 🚧 EN COURS - Fondations établies
📊 État Actuel
Tests Créés et Passants ✅
| Feature | Use Case Testé | Status | Tests |
|---|---|---|---|
| Profile | GetProfile | ✅ PASS | 4/4 tests passés |
| Settings | ResetSettings | ✅ PASS | 4/4 tests passés |
Total: 8/8 tests passés (100%)
Tests Créés avec Erreurs ❌
| Feature | Use Case | Problème |
|---|---|---|
| Contributions | GetContributions | Propriétés modèle non concordantes |
🏗️ Infrastructure de Tests Mise en Place
1. Structure de Dossiers
test/features/
├── finance_workflow/domain/usecases/
├── contributions/domain/usecases/
├── events/domain/usecases/
├── members/domain/usecases/
├── profile/domain/usecases/ ✅ GetProfile tests
├── organizations/domain/usecases/
├── reports/domain/usecases/
└── settings/domain/usecases/ ✅ ResetSettings tests
2. Dépendances de Test (pubspec.yaml)
✅ Configuré:
mockito: ^5.4.4- Mocking frameworkbloc_test: ^9.1.7- BLoC testing utilitiesbuild_runner: ^2.4.13- Code generationflutter_test: sdk- Flutter testing frameworkintegration_test: sdk- Integration testing
3. Build Runner
✅ Configuré et fonctionnel:
flutter pub run build_runner build --delete-conflicting-outputs
# Succeeded after 27.9s with 18 outputs (38 actions)
4. Pattern de Test Établi
Use Case Test Template:
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:unionflow_mobile_apps/features/.../domain/repositories/...repository.dart';
import 'package:unionflow_mobile_apps/features/.../domain/usecases/...usecase.dart';
@GenerateMocks([IRepository])
import 'test_name_test.mocks.dart';
void main() {
late UseCase useCase;
late MockIRepository mockRepository;
setUp(() {
mockRepository = MockIRepository();
useCase = UseCase(mockRepository);
});
group('UseCase Test Group', () {
test('should perform expected behavior', () async {
// Arrange
when(mockRepository.method(...)).thenAnswer((_) async => expectedResult);
// Act
final result = await useCase(...);
// Assert
expect(result, equals(expectedResult));
verify(mockRepository.method(...));
verifyNoMoreInteractions(mockRepository);
});
});
}
✅ Tests Réussis - Détails
GetProfile (4/4 tests ✅)
Fichier: test/features/profile/domain/usecases/get_profile_test.dart
Tests:
- ✅ Should return current user profile from repository
- ✅ Should return null when user is not authenticated
- ✅ Should throw exception when repository throws
- ✅ Should cache profile data on successful retrieval
Résultats:
00:00 +4: All tests passed!
Mock utilisé: MockIProfileRepository
Modèle: MembreCompletModel (3 champs requis: nom, prenom, email)
ResetSettings (4/4 tests ✅)
Fichier: test/features/settings/domain/usecases/reset_settings_test.dart
Tests:
- ✅ Should reset configuration to default values
- ✅ Should handle fallback when reset endpoint fails
- ✅ Should throw exception when all reset strategies fail
- ✅ Should return valid config with minimal required fields
Résultats:
00:00 +4: ResetSettings Use Case - All tests passed!
Mock utilisé: MockISystemConfigRepository
Modèle: SystemConfigModel (tous champs optionnels)
📋 Prochaines Étapes
Phase 1: Corriger Tests Existants
- Fixer GetContributions (corriger propriétés modèle)
- Regénérer mocks avec build_runner
- Vérifier 100% tests passants
Phase 2: Créer Tests pour Features P1 (26 use cases)
Contributions (8 use cases):
- get_contributions.dart
- get_contribution_by_id.dart
- create_contribution.dart
- update_contribution.dart
- delete_contribution.dart
- pay_contribution.dart
- get_contribution_history.dart
- get_contribution_stats.dart
Events (10 use cases):
- get_events.dart
- get_event_by_id.dart
- create_event.dart
- update_event.dart
- delete_event.dart
- register_for_event.dart
- cancel_registration.dart
- get_my_registrations.dart
- get_event_participants.dart
- submit_event_feedback.dart
Members (8 use cases):
- get_members.dart
- get_member_by_id.dart
- create_member.dart
- update_member.dart
- delete_member.dart
- search_members.dart
- export_members.dart
- get_member_stats.dart
Phase 3: Créer Tests pour Features P2 (18 use cases)
Organizations (7 use cases):
- get_organizations.dart
- get_organization_by_id.dart
- create_organization.dart
- update_organization.dart
- delete_organization.dart
- get_organization_members.dart
- update_organization_config.dart
Reports (6 use cases):
- get_reports.dart
- generate_report.dart
- export_report_pdf.dart
- export_report_excel.dart
- schedule_report.dart
- get_scheduled_reports.dart
Settings (5 use cases):
- ✅ reset_settings.dart (4/4 tests)
- get_settings.dart
- update_settings.dart
- get_cache_stats.dart
- clear_cache.dart
Phase 4: Tests BLoC (10 BLoCs)
Pour chaque BLoC, tester:
- État initial
- Transitions d'états
- Gestion d'erreurs
- Appels use cases corrects
Utiliser bloc_test package:
blocTest<MyBloc, MyState>(
'emits [MyState] when event is added',
build: () => MyBloc(mockUseCase),
act: (bloc) => bloc.add(MyEvent()),
expect: () => [MyExpectedState()],
);
Phase 5: Tests d'Intégration
- Tests end-to-end flows critiques
- Tests avec backend mock complet
- Tests de navigation
- Tests de persistance
🎯 Objectif Final
| Métrique | Cible | Actuel | % |
|---|---|---|---|
| Use Cases testés | 64 | 2 | 3% |
| Tests unitaires | ~256 (4/use case) | 8 | 3% |
| BLoCs testés | 10 | 0 | 0% |
| Coverage | 80% | ~5% | 6% |
🔧 Commandes Utiles
Générer mocks:
flutter pub run build_runner build --delete-conflicting-outputs
Exécuter tous les tests:
flutter test
Exécuter tests spécifiques:
flutter test test/features/profile/domain/usecases/
Coverage report:
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html
📝 Notes Techniques
Gotchas Rencontrés
-
Noms de classes/fichiers incohérents:
- Fichier:
membre_complete_model.dart - Classe:
MembreCompletModel(sans 'e' final) - ⚠️ Toujours vérifier le nom exact de la classe
- Fichier:
-
Propriétés de modèles:
- Toujours lire le fichier modèle pour connaître les vraies propriétés
- Ne pas inventer de propriétés dans les tests
-
Génération de mocks:
- Exécuter build_runner après chaque modification de
@GenerateMocks - Les mocks sont générés dans
*.mocks.dart
- Exécuter build_runner après chaque modification de
-
Imports:
- Repository: depuis
domain/repositories/ - Use case: depuis
domain/usecases/ - Modèles: depuis
data/models/
- Repository: depuis
Fondations établies par: Claude Code Date: 2026-03-14 Statut: ✅ Infrastructure prête - Prochaine étape: Créer tests pour 62 use cases restants