Implémentation complète d'un système de tests d'intégration modulaire pour valider AISSIA en conditions réelles. Architecture "Un module = Un test": - Chaque test est un module GroveEngine (.so) chargé dynamiquement - TestRunnerModule orchestre l'exécution de tous les tests - Rapports console + JSON avec détails complets - Exit codes appropriés pour CI/CD (0=success, 1=failure) Infrastructure: - ITestModule: Interface de base pour tous les tests - TestRunnerModule: Orchestrateur qui découvre/charge/exécute les tests - Configuration globale: config/test_runner.json - Flag --run-tests pour lancer les tests Tests implémentés (8/8 passing): Phase 1 - Tests MCP: ✅ IT_001_GetCurrentTime: Test tool get_current_time via AI ✅ IT_002_FileSystemWrite: Test tool filesystem_write ✅ IT_003_FileSystemRead: Test tool filesystem_read ✅ IT_004_MCPToolsList: Vérification inventaire tools (≥5) Phase 2 - Tests Flux: ✅ IT_005_VoiceToAI: Communication Voice → AI ✅ IT_006_AIToLLM: Requête AI → Claude API (réelle) ✅ IT_007_StorageWrite: AI → Storage (sauvegarde note) ✅ IT_008_StorageRead: AI → Storage (lecture note) Avantages: 🔥 Hot-reload ready: Tests modifiables sans recompiler 🌐 Conditions réelles: Vraies requêtes Claude API, vrais fichiers 🎯 Isolation: Chaque test indépendant, cleanup automatique 📊 Rapports complets: Console + JSON avec détails par test ✅ CI/CD ready: Exit codes, JSON output, automation-friendly Usage: cmake --build build --target integration_tests cd build && ./aissia --run-tests 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
471 lines
15 KiB
Markdown
471 lines
15 KiB
Markdown
# Prompt pour Implémenter le Système de Tests d'Intégration
|
|
|
|
Salut ! Je reprends l'implémentation du **système de tests d'intégration** pour AISSIA.
|
|
|
|
## Contexte
|
|
|
|
AISSIA est un assistant vocal agentique en C++17 basé sur GroveEngine. Le projet utilise une architecture modulaire avec hot-reload et communication pub/sub via IIO.
|
|
|
|
**État actuel** :
|
|
- ✅ 7 modules fonctionnels (Scheduler, Notification, Monitoring, AI, Voice, Storage, Web)
|
|
- ✅ 120/120 tests unitaires passent (Catch2)
|
|
- ✅ LLM Service avec Claude Sonnet 4
|
|
- ✅ 17+ MCP tools internes
|
|
- ✅ Services infrastructure opérationnels
|
|
|
|
**Problème** : Pas de tests d'intégration end-to-end pour valider le système complet en conditions réelles.
|
|
|
|
## Objectif
|
|
|
|
Implémenter un **système de tests d'intégration modulaire** où chaque test est un module GroveEngine indépendant, chargé dynamiquement par un orchestrateur (TestRunnerModule).
|
|
|
|
## Plan d'Implémentation
|
|
|
|
Le plan complet est dans `plans/integration-tests-plan.md`. Lis-le attentivement avant de commencer.
|
|
|
|
**Résumé des phases** :
|
|
|
|
### Phase 1: Infrastructure (2h)
|
|
1. Créer `src/shared/testing/ITestModule.h` (interface de base)
|
|
2. Créer `src/modules/TestRunnerModule.{h,cpp}` (orchestrateur)
|
|
3. Créer `config/test_runner.json` + `config/integration/`
|
|
4. Modifier `src/main.cpp` pour ajouter `--run-tests` flag
|
|
5. Ajouter targets au `CMakeLists.txt`
|
|
|
|
### Phase 2: Tests MCP (3h)
|
|
6. Créer `IT_001_GetCurrentTime.cpp` (test tool get_current_time)
|
|
7. Créer `IT_002_FileSystemWrite.cpp` (test filesystem_write)
|
|
8. Créer `IT_003_FileSystemRead.cpp` (test filesystem_read)
|
|
9. Créer `IT_004_MCPToolsList.cpp` (inventaire tools)
|
|
|
|
### Phase 3: Tests Flux (3h)
|
|
10. Créer `IT_005_VoiceToAI.cpp` (Voice → AI)
|
|
11. Créer `IT_006_AIToLLM.cpp` (AI → LLM Claude API)
|
|
12. Créer `IT_007_StorageWrite.cpp` (AI → Storage écriture)
|
|
13. Créer `IT_008_StorageRead.cpp` (AI → Storage lecture)
|
|
|
|
### Phase 4: Test Complet (2h)
|
|
14. Créer `IT_009_FullConversationLoop.cpp` (flux end-to-end)
|
|
|
|
### Phase 5: Tests Modules (1h)
|
|
15. Créer `IT_010_SchedulerHyperfocus.cpp`
|
|
16. Créer `IT_011_NotificationAlert.cpp`
|
|
17. Créer `IT_012_MonitoringActivity.cpp`
|
|
18. Créer `IT_013_WebRequest.cpp`
|
|
|
|
### Phase 6: Finition (1h)
|
|
19. Documenter dans README.md
|
|
20. Valider et commit
|
|
|
|
## Contraintes Importantes
|
|
|
|
### Règles GroveEngine
|
|
|
|
- **Un test = Un module** (.so indépendant)
|
|
- **Interface commune** : Tous héritent de `ITestModule`
|
|
- **Communication IIO** : Tests publient/subscribe via IIO
|
|
- **Isolation** : Chaque test ne pollue pas les autres
|
|
- **Hot-reload ready** : Tests modifiables sans recompiler tout
|
|
|
|
### Architecture du TestRunner
|
|
|
|
**TestRunnerModule** :
|
|
1. Scan `tests/integration/` pour trouver tous les `IT_*.so`
|
|
2. Pour chaque test :
|
|
- Charge dynamiquement le module
|
|
- Execute via `process()`
|
|
- Récupère résultat via `getHealthStatus()`
|
|
- Décharge le module
|
|
3. Génère rapport (console + JSON)
|
|
4. Exit avec code approprié (0 = success, 1 = failure)
|
|
|
|
### Structure d'un Test Module
|
|
|
|
Voir exemple complet dans le plan section 4.1. Résumé :
|
|
|
|
```cpp
|
|
class IT_XXX_TestName : public ITestModule {
|
|
public:
|
|
std::string getTestName() const override;
|
|
std::string getDescription() const override;
|
|
|
|
void setConfiguration(...) override {
|
|
// Subscribe aux topics nécessaires
|
|
}
|
|
|
|
TestResult execute() override {
|
|
// 1. Publier message IIO
|
|
// 2. Attendre réponse (avec timeout)
|
|
// 3. Valider contenu
|
|
// 4. Retourner résultat
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<IDataNode> waitForResponse(topic, timeout);
|
|
};
|
|
|
|
extern "C" {
|
|
grove::IModule* createModule() { return new IT_XXX_TestName(); }
|
|
void destroyModule(grove::IModule* m) { delete m; }
|
|
}
|
|
```
|
|
|
|
### Protocole IIO pour Tests
|
|
|
|
**Topics importants** :
|
|
- `ai:query` → Envoyer question à l'AI
|
|
- `llm:request` → Requête vers LLM Service
|
|
- `llm:response` → Réponse de Claude API
|
|
- `voice:transcription` → Simulation transcription vocale
|
|
- `storage:save_note` → Sauvegarder note (via tool)
|
|
- `storage:query_notes` → Lire notes (via tool)
|
|
- `web:request` / `web:response` → HTTP requests
|
|
- `scheduler:*`, `notification:*`, `monitoring:*` → Modules spécifiques
|
|
|
|
## Fichiers à Créer/Modifier
|
|
|
|
### Nouveaux fichiers
|
|
|
|
**Infrastructure** :
|
|
- [ ] `src/shared/testing/ITestModule.h`
|
|
- [ ] `src/modules/TestRunnerModule.h`
|
|
- [ ] `src/modules/TestRunnerModule.cpp`
|
|
- [ ] `config/test_runner.json`
|
|
- [ ] `config/integration/IT_001.json` (et suivants)
|
|
|
|
**Tests MCP** :
|
|
- [ ] `tests/integration/IT_001_GetCurrentTime.cpp`
|
|
- [ ] `tests/integration/IT_002_FileSystemWrite.cpp`
|
|
- [ ] `tests/integration/IT_003_FileSystemRead.cpp`
|
|
- [ ] `tests/integration/IT_004_MCPToolsList.cpp`
|
|
|
|
**Tests Flux** :
|
|
- [ ] `tests/integration/IT_005_VoiceToAI.cpp`
|
|
- [ ] `tests/integration/IT_006_AIToLLM.cpp`
|
|
- [ ] `tests/integration/IT_007_StorageWrite.cpp`
|
|
- [ ] `tests/integration/IT_008_StorageRead.cpp`
|
|
|
|
**Test Complet** :
|
|
- [ ] `tests/integration/IT_009_FullConversationLoop.cpp`
|
|
|
|
**Tests Modules** :
|
|
- [ ] `tests/integration/IT_010_SchedulerHyperfocus.cpp`
|
|
- [ ] `tests/integration/IT_011_NotificationAlert.cpp`
|
|
- [ ] `tests/integration/IT_012_MonitoringActivity.cpp`
|
|
- [ ] `tests/integration/IT_013_WebRequest.cpp`
|
|
|
|
### Fichiers à modifier
|
|
|
|
- [ ] `CMakeLists.txt` (ajouter target integration_tests)
|
|
- [ ] `src/main.cpp` (ajouter flag --run-tests)
|
|
- [ ] `README.md` (documenter système de tests)
|
|
|
|
## Tests à Implémenter
|
|
|
|
### Priorité HAUTE : Tests MCP
|
|
|
|
**IT_001_GetCurrentTime** :
|
|
- Envoie `ai:query` : "Quelle heure est-il ?"
|
|
- Attend `llm:response` (timeout 10s)
|
|
- Vérifie réponse contient timestamp valide (format HH:MM)
|
|
- Critère succès : Timestamp présent et cohérent
|
|
|
|
**IT_002_FileSystemWrite** :
|
|
- Envoie `ai:query` : "Écris 'Test réussi' dans le fichier test_output.md"
|
|
- Attend `llm:response`
|
|
- Vérifie fichier `data/test_output.md` créé avec bon contenu
|
|
- Critère succès : Fichier existe + contenu correct
|
|
|
|
**IT_003_FileSystemRead** :
|
|
- Pré-condition : Créer fichier `data/test_input.md` avec "Hello World"
|
|
- Envoie `ai:query` : "Lis le contenu de test_input.md"
|
|
- Attend `llm:response`
|
|
- Vérifie réponse contient "Hello World"
|
|
- Critère succès : Contenu lu correctement
|
|
|
|
**IT_004_MCPToolsList** :
|
|
- Envoie `ai:query` : "Liste tous tes tools disponibles"
|
|
- Attend `llm:response`
|
|
- Parse JSON pour compter les tools
|
|
- Critère succès : Au moins 17 tools présents
|
|
|
|
### Priorité HAUTE : Tests Flux
|
|
|
|
**IT_005_VoiceToAI** :
|
|
- Publie `voice:transcription` : {"text": "Bonjour", "confidence": 0.95}
|
|
- Attend `llm:request` publié par AIModule
|
|
- Critère succès : AIModule a bien reçu et traité la transcription
|
|
|
|
**IT_006_AIToLLM** :
|
|
- Publie `ai:query` : "Quel est le sens de la vie ?"
|
|
- Attend `llm:response` de Claude API (timeout 30s)
|
|
- Vérifie réponse non vide, pas d'erreur
|
|
- Critère succès : Réponse cohérente de Claude
|
|
|
|
**IT_007_StorageWrite** :
|
|
- Envoie `ai:query` : "Sauvegarde une note : 'Test integration'"
|
|
- Attend confirmation
|
|
- Vérifie fichier .md créé dans `data/notes/`
|
|
- Critère succès : Note sauvegardée
|
|
|
|
**IT_008_StorageRead** :
|
|
- Pré-condition : Note "Test data" existe
|
|
- Envoie `ai:query` : "Récupère mes notes contenant 'Test'"
|
|
- Vérifie réponse contient "Test data"
|
|
- Critère succès : Note récupérée correctement
|
|
|
|
### Priorité HAUTE : Test End-to-End
|
|
|
|
**IT_009_FullConversationLoop** :
|
|
- Scénario complet :
|
|
1. Voice : "Prends note que j'aime le C++"
|
|
2. AI → LLM (appelle tool storage_save_note)
|
|
3. Storage sauvegarde dans .md
|
|
4. Voice : "Qu'est-ce que j'aime ?"
|
|
5. AI → LLM (appelle tool storage_query_notes)
|
|
6. Storage récupère la note
|
|
7. LLM répond : "Vous aimez le C++"
|
|
8. Voice reçoit réponse
|
|
- Critère succès : Chaque étape validée, boucle complète fonctionne
|
|
|
|
### Priorité MOYENNE : Tests Modules
|
|
|
|
**IT_010_SchedulerHyperfocus** :
|
|
- Publie `scheduler:work_session` : {duration: 121, task: "coding"}
|
|
- Attend `scheduler:hyperfocus_detected`
|
|
- Critère succès : Hyperfocus détecté après 120min
|
|
|
|
**IT_011_NotificationAlert** :
|
|
- Publie `notification:alert` : {title: "Test", priority: "URGENT"}
|
|
- Vérifie logs contiennent message
|
|
- Critère succès : Notification affichée
|
|
|
|
**IT_012_MonitoringActivity** :
|
|
- Publie `platform:window_changed` : {app: "VSCode"}
|
|
- Attend `monitoring:activity_classified`
|
|
- Critère succès : App classée comme productive
|
|
|
|
**IT_013_WebRequest** :
|
|
- Publie `web:request` : {url: "https://api.github.com", method: "GET"}
|
|
- Attend `web:response`
|
|
- Vérifie statusCode 200
|
|
- Critère succès : Réponse HTTP reçue
|
|
|
|
## Format des Résultats Attendu
|
|
|
|
### Console (exemple)
|
|
|
|
```
|
|
========================================
|
|
AISSIA Integration Tests
|
|
Running 13 tests...
|
|
========================================
|
|
|
|
[1/13] IT_001_GetCurrentTime..................... ✅ PASS (1.2s)
|
|
Tool returned valid time
|
|
|
|
[2/13] IT_002_FileSystemWrite.................... ✅ PASS (0.8s)
|
|
File created: data/test_output.md
|
|
|
|
...
|
|
|
|
========================================
|
|
Results: 13/13 passed (100%)
|
|
Total time: 25.2s
|
|
========================================
|
|
|
|
Exit code: 0
|
|
```
|
|
|
|
### JSON (`test-results.json`)
|
|
|
|
```json
|
|
{
|
|
"summary": {
|
|
"total": 13,
|
|
"passed": 13,
|
|
"failed": 0,
|
|
"successRate": 100,
|
|
"totalDurationMs": 25200
|
|
},
|
|
"tests": [
|
|
{
|
|
"name": "IT_001_GetCurrentTime",
|
|
"passed": true,
|
|
"message": "Tool returned valid time",
|
|
"durationMs": 1200,
|
|
"details": {
|
|
"response": "Il est 17:45:23"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Validation
|
|
|
|
### Build & Tests
|
|
|
|
```bash
|
|
# Build infrastructure + tests
|
|
cmake -B build -DBUILD_TESTING=ON
|
|
cmake --build build --target integration_tests -j4
|
|
|
|
# Vérifier modules créés
|
|
ls build/tests/integration/
|
|
# IT_001_GetCurrentTime.so
|
|
# IT_002_FileSystemWrite.so
|
|
# ...
|
|
|
|
# Lancer les tests
|
|
./build/aissia --run-tests
|
|
|
|
# Vérifier exit code
|
|
echo $? # Doit être 0 si tous passent
|
|
```
|
|
|
|
### Critères de Succès
|
|
|
|
**Objectif : 13/13 tests passent** en conditions réelles avec :
|
|
- ✅ MCP tools fonctionnent
|
|
- ✅ Claude API répond (vraies requêtes)
|
|
- ✅ Storage lit/écrit fichiers .md
|
|
- ✅ Communication IIO entre tous les modules
|
|
- ✅ Flux complet Voice→AI→LLM→Storage→Voice
|
|
|
|
### Performance
|
|
|
|
- ✅ Suite complète < 60s
|
|
- ✅ Chaque test < 10s (sauf IT_009 < 15s)
|
|
|
|
### Qualité
|
|
|
|
- ✅ Pas de warnings de compilation
|
|
- ✅ Code suit le style existant
|
|
- ✅ Logs clairs et informatifs
|
|
- ✅ Cleanup des fichiers .md de test
|
|
- ✅ Tests reproductibles (pas de flakiness)
|
|
|
|
## Commandes Utiles
|
|
|
|
```bash
|
|
# Build complet
|
|
cmake -B build -DBUILD_TESTING=ON
|
|
cmake --build build -j4
|
|
|
|
# Build seulement integration tests
|
|
cmake --build build --target integration_tests
|
|
|
|
# Run tests avec verbose
|
|
./build/aissia --run-tests --verbose
|
|
|
|
# Run tests avec JSON output
|
|
./build/aissia --run-tests --json-output results.json
|
|
|
|
# Run un seul test (debug)
|
|
# (charger manuellement le .so dans le code)
|
|
|
|
# Git
|
|
git add -A
|
|
git commit -m "feat: Add integration test system with dynamic modules"
|
|
git push
|
|
```
|
|
|
|
## Ressources
|
|
|
|
### Fichiers de référence
|
|
|
|
- `src/modules/AIModule.cpp` - Exemple module bien structuré
|
|
- `src/modules/WebModule.cpp` - Module récent, bon pattern
|
|
- `tests/modules/AIModuleTests.cpp` - Pattern de tests unitaires
|
|
- `src/services/LLMService.cpp` - Utilisation Claude API
|
|
- `src/shared/tools/InternalTools.cpp` - MCP tools implementation
|
|
|
|
### Documentation
|
|
|
|
- `plans/integration-tests-plan.md` - Plan complet détaillé ⭐
|
|
- `docs/GROVEENGINE_GUIDE.md` - Guide GroveEngine
|
|
- `CLAUDE.md` - Règles de développement
|
|
|
|
## Notes Importantes
|
|
|
|
### 1. Conditions Réelles
|
|
|
|
**Les tests utilisent de vraies ressources** :
|
|
- **Claude API** : Vraies requêtes (coût/tokens)
|
|
- **Fichiers** : Écriture dans `data/` (cleanup nécessaire)
|
|
- **Réseau** : Requêtes HTTP réelles (IT_013)
|
|
|
|
→ Les tests peuvent échouer si API down ou network issue
|
|
|
|
### 2. Timeout Management
|
|
|
|
Chaque test a un timeout configurable :
|
|
- Tests MCP simples : 5-10s
|
|
- Tests LLM : 30s (Claude peut être lent)
|
|
- Test complet (IT_009) : 60s
|
|
|
|
→ Utilise `waitForResponse()` helper avec timeout
|
|
|
|
### 3. ITestModule vs IModule
|
|
|
|
`ITestModule` hérite de `IModule` mais ajoute :
|
|
- `TestResult execute()` - Point d'entrée du test
|
|
- `std::string getTestName()` - Nom unique
|
|
- `std::string getDescription()` - Description
|
|
|
|
### 4. TestRunnerModule Workflow
|
|
|
|
1. **Découverte** : Scan filesystem pour `IT_*.so`
|
|
2. **Chargement** : `ModuleLoader::load()` pour chaque test
|
|
3. **Configuration** : Passe config JSON au test
|
|
4. **Exécution** : Appelle `execute()` qui retourne `TestResult`
|
|
5. **Déchargement** : `ModuleLoader::unload()`
|
|
6. **Rapport** : Agrège tous les résultats
|
|
|
|
### 5. Error Handling
|
|
|
|
Chaque test doit :
|
|
- Catcher toutes les exceptions
|
|
- Retourner `TestResult` avec `passed = false` en cas d'erreur
|
|
- Fournir message clair dans `result.message`
|
|
- Ne JAMAIS crasher (sinon TestRunner crash)
|
|
|
|
### 6. Cleanup
|
|
|
|
Tests qui créent des fichiers doivent :
|
|
- Utiliser préfixe `test_` dans les noms
|
|
- Nettoyer les fichiers à la fin (optionnel, car TestRunner peut le faire)
|
|
- Ou utiliser dossier `data/test/` temporaire
|
|
|
|
## Questions Fréquentes
|
|
|
|
**Q: Comment tester sans consommer des tokens Claude ?**
|
|
R: Pour l'instant, on accepte le coût. Dans une v2, on pourrait ajouter un flag `--mock-llm` qui utilise des réponses pré-enregistrées.
|
|
|
|
**Q: Un test échoue de manière aléatoire (flakiness) ?**
|
|
R: Augmente le timeout. Les tests réseau/LLM peuvent être lents. Si le problème persiste, logge plus d'infos pour debugger.
|
|
|
|
**Q: Comment débugger un test spécifique ?**
|
|
R: Tu peux charger le test manuellement dans le code et l'exécuter avec gdb. Ou ajoute plus de logs dans le test.
|
|
|
|
**Q: Les tests doivent-ils être parallèles ?**
|
|
R: Non, séquentiels pour l'instant. Parallélisation = Phase 7 (extensions futures).
|
|
|
|
**Q: Faut-il tester le hot-reload ?**
|
|
R: Pas pour la v1. C'est IT_014 dans les extensions futures.
|
|
|
|
---
|
|
|
|
**Bonne chance !** Suis le plan étape par étape. L'objectif est d'avoir un système de tests modulaire, extensible et qui démontre la puissance de GroveEngine.
|
|
|
|
**Timeline suggérée** :
|
|
- Jour 1 : Phase 1 (Infrastructure)
|
|
- Jour 2 : Phase 2 (Tests MCP)
|
|
- Jour 3 : Phase 3 (Tests Flux)
|
|
- Jour 4 : Phase 4 (Test Complet)
|
|
- Jour 5 : Phase 5 (Tests Modules) + Phase 6 (Finition)
|
|
|
|
**Auteur du plan** : Claude Code (Session 2025-11-28)
|
|
**Date** : 2025-11-28
|