Guide de Correction de Bugs
Ce guide couvre l'approche systématique pour corriger les bugs avec Claude-Craft, du diagnostic à la validation.
Table des Matières
- Workflow de Correction de Bugs
- Phase 1 : Reproduire
- Phase 2 : Diagnostiquer
- Phase 3 : Écrire le Test de Régression
- Phase 4 : Corriger
- Phase 5 : Valider
- Phase 6 : Documenter
- Procédures Hotfix
- Exemple Complet
Workflow de Correction de Bugs
L'approche systématique pour corriger les bugs :
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1. Reproduire│ --> │2. Diagnostiquer│ --> │ 3. Test │
└─────────────┘ └─────────────┘ └─────────────┘
│
v
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 6. Documenter│ <-- │ 5. Valider │ <-- │ 4. Corriger │
└─────────────┘ └─────────────┘ └─────────────┘Pourquoi Cette Approche ?
- Reproduire d'abord : On ne peut pas corriger ce qu'on ne voit pas
- Tester avant de corriger : Prouve que le bug existe et est corrigé
- Valider en profondeur : Assure qu'il n'y a pas de régression
- Documenter : Aide à prévenir des bugs similaires
Phase 1 : Reproduire
Avant de corriger, reproduisez le bug de manière consistante.
Collecter les Informations
Collecter depuis le rapport de bug :
- Étapes pour reproduire
- Comportement attendu
- Comportement réel
- Environnement (version, OS, etc.)
- Messages d'erreur/logs
- Captures d'écran si applicable
Créer l'Environnement de Reproduction
# Checkout de la version problématique
git checkout <commit-ou-tag>
# Configurer l'environnement identique
make docker-up
# Reproduire avec les étapes exactesVérifier la Reproduction
Pouvez-vous déclencher le bug de manière consistante ?
- [ ] Le bug survient avec les étapes rapportées
- [ ] Le bug survient dans le même environnement
- [ ] Le bug est déterministe (pas aléatoire)
Si Vous Ne Pouvez Pas Reproduire
@research-assistant Aide-moi à comprendre pourquoi ce bug pourrait être spécifique à l'environnement
Rapport de bug :
- L'utilisateur voit l'erreur X en faisant Y
- Je ne peux pas reproduire localement
- L'utilisateur est sur l'environnement Z
Causes possibles ?Phase 2 : Diagnostiquer
Trouvez la cause racine du bug.
Utiliser la Commande d'Analyse
/common:analyze-bug "Les utilisateurs ne peuvent pas se connecter avec les bons identifiants après réinitialisation du mot de passe"Cette commande va :
- Suggérer des zones à investiguer
- Identifier les causes potentielles
- Recommander des étapes de débogage
- Lister les zones de code liées
Utiliser le Coach TDD pour le Diagnostic
@tdd-coach Aide-moi à diagnostiquer ce bug d'authentification
Symptômes :
- L'utilisateur réinitialise son mot de passe avec succès
- Le nouveau mot de passe est sauvegardé (confirmé en BDD)
- La connexion échoue avec "identifiants invalides"
- L'ancien mot de passe ne fonctionne pas non plus
Que dois-je investiguer ?Techniques de Débogage
Ajouter du Logging
// Logging de debug temporaire
$this->logger->debug('Vérification mot de passe', [
'user_id' => $user->getId(),
'stored_hash' => substr($user->getPasswordHash(), 0, 20) . '...',
'verification_result' => $result,
]);Inspecter l'État de la Base de Données
-- Vérifier l'état utilisateur après réinitialisation
SELECT id, email, password_hash, updated_at
FROM users
WHERE email = 'user@example.com';Tracer le Chemin d'Exécution
// Ajouter une stack trace aux points suspects
debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);Identifier la Cause Racine
Catégories courantes :
- Erreur de logique : Mauvaise condition ou calcul
- Erreur d'état : État de données incorrect
- Condition de concurrence : Comportement dépendant du timing
- Erreur d'intégration : Problème de service externe
- Erreur de configuration : Mauvais paramètres
Checklist de Diagnostic
- [ ] Bug reproduit de manière consistante
- [ ] Emplacement de l'erreur identifié
- [ ] Cause racine comprise
- [ ] Zones de code liées identifiées
- [ ] Approche de correction déterminée
Phase 3 : Écrire le Test de Régression
Écrivez un test qui échoue AVANT la correction et passe APRÈS.
Pourquoi Tester d'Abord ?
- Prouve que le bug existe : Le test échoue avec le code actuel
- Prouve que la correction fonctionne : Le test passe après la correction
- Prévient la régression : Le test détecte les futurs problèmes
- Documente le comportement : Le test décrit le comportement attendu
Utiliser le Coach TDD
@tdd-coach Aide-moi à écrire un test de régression pour ce bug
Bug : La réinitialisation de mot de passe ne met pas à jour le hash correctement
Comportement attendu :
- L'utilisateur demande une réinitialisation
- L'utilisateur définit un nouveau mot de passe
- L'utilisateur peut se connecter avec le nouveau mot de passe
Comportement réel :
- La connexion échoue après réinitialisationExemple de Test de Régression
/**
* @test
* @see https://github.com/company/project/issues/123
*
* Bug : Les utilisateurs ne pouvaient pas se connecter après réinitialisation
* Cause : Le hash de mot de passe n'était pas persisté correctement
*/
public function test_user_can_login_after_password_reset(): void
{
// Arrange : Créer un utilisateur avec un mot de passe connu
$user = $this->createUser('user@example.com', 'ancien-mot-de-passe');
// Act : Réinitialiser le mot de passe
$this->passwordResetService->resetPassword($user, 'nouveau-mot-de-passe');
// Assert : Peut se connecter avec le nouveau mot de passe
$result = $this->authService->authenticate('user@example.com', 'nouveau-mot-de-passe');
$this->assertTrue($result->isSuccess());
$this->assertNotNull($result->getToken());
}
/**
* @test
* Lié : S'assurer que l'ancien mot de passe ne fonctionne plus
*/
public function test_old_password_fails_after_reset(): void
{
$user = $this->createUser('user@example.com', 'ancien-mot-de-passe');
$this->passwordResetService->resetPassword($user, 'nouveau-mot-de-passe');
$result = $this->authService->authenticate('user@example.com', 'ancien-mot-de-passe');
$this->assertFalse($result->isSuccess());
}Checklist d'Écriture de Test
- [ ] Le test reproduit le bug (échoue avant la correction)
- [ ] Le test a un nom descriptif
- [ ] Le test référence le numéro d'issue
- [ ] Le test documente la cause racine en commentaire
- [ ] Les cas limites liés sont testés
Phase 4 : Corriger
Implémentez la correction minimale pour le bug.
Directives de Correction
- Changement minimal : Ne corrigez que le bug, ne refactorisez pas
- Intention claire : Le code doit montrer ce qui était incorrect
- Pas d'effets de bord : Ne changez pas de comportement non lié
- Maintenez le style : Suivez les patterns du code existant
Exemple de Correction
// AVANT (bugué)
public function resetPassword(User $user, string $newPassword): void
{
$hash = $this->hasher->hash($newPassword);
$user->setPasswordHash($hash);
// Bug : persist/flush manquants !
}
// APRÈS (corrigé)
public function resetPassword(User $user, string $newPassword): void
{
$hash = $this->hasher->hash($newPassword);
$user->setPasswordHash($hash);
$this->entityManager->persist($user); // <-- Correction
$this->entityManager->flush(); // <-- Correction
}Exécuter le Test de Régression
# Le test devrait maintenant passer
make test-unit TEST=tests/Unit/PasswordResetTest.php
# Ou exécuter un test spécifique
./vendor/bin/phpunit --filter test_user_can_login_after_password_resetChecklist de Correction
- [ ] Le test de régression passe maintenant
- [ ] La correction est minimale et ciblée
- [ ] Pas de changements non liés inclus
- [ ] Style de code maintenu
Phase 5 : Valider
Assurez-vous que la correction ne casse rien d'autre.
Exécuter la Suite de Tests Complète
# Tous les tests unitaires
make test-unit
# Tous les tests d'intégration
make test-integration
# Suite complète de tests
make testVérifications Qualité
# Qualité du code (par technologie)
/symfony:check-code-quality
/flutter:check-code-quality
/python:check-code-quality
# Sécurité (si la correction touche du code sensible)
/common:security-audit
# Conformité complète
/symfony:check-complianceTests Manuels
Même avec des tests automatisés, vérifiez manuellement :
- Suivez les étapes de reproduction originales
- Vérifiez que le bug ne survient plus
- Testez les fonctionnalités liées
- Vérifiez les cas limites
Utiliser l'Agent Reviewer
@symfony-reviewer Revois ma correction pour l'issue #123
Bug : Les utilisateurs ne pouvaient pas se connecter après réinitialisation
Correction : Ajout des appels persist/flush manquants dans resetPassword()
Fichiers modifiés :
- src/Application/Service/PasswordResetService.php
- tests/Unit/PasswordResetTest.php
Vérifie s'il te plaît :
1. La correction est correcte et complète
2. Pas d'effets de bord
3. Couverture de test adéquateChecklist de Validation
- [ ] Le test de régression passe
- [ ] Tous les tests existants passent
- [ ] L'analyse statique passe
- [ ] Les tests manuels confirment la correction
- [ ] Revue de code effectuée
Phase 6 : Documenter
Documentez la correction pour référence future.
Format du Message de Commit
fix(auth): résoudre l'échec de connexion après réinitialisation mot de passe
Bug : Les utilisateurs ne pouvaient pas se connecter après réinitialisation
Cause racine : Le changement de hash n'était pas persisté en base de données
Correction : Ajout des appels persist() et flush() dans PasswordResetService
Closes #123
Test : test_user_can_login_after_password_resetMettre à Jour le Tracker d'Issues
## Résolution
**Cause Racine :**
La méthode `resetPassword()` dans `PasswordResetService` mettait à jour le
hash de mot de passe en mémoire mais ne persistait pas le changement en base.
**Correction :**
Ajout des appels `persist()` et `flush()` après la définition du nouveau hash.
**Tests :**
- Ajout du test de régression `test_user_can_login_after_password_reset`
- Ajout du test de cas limite `test_old_password_fails_after_reset`
**Prévention :**
Considérer l'ajout d'un point de checklist de revue de code pour les opérations de persistance.Entrée Base de Connaissances (si pattern récurrent)
# Bug Courant : Changements d'Entité Non Persistés
## Symptômes
- Les changements de données semblent fonctionner (pas d'erreur)
- Les changements n'apparaissent pas en base de données
- Les changements sont perdus après rafraîchissement
## Cause Racine
Appels `persist()` et/ou `flush()` manquants dans Doctrine.
## Pattern de Correction
```php
$entity->setSomething($value);
$this->entityManager->persist($entity); // Ne pas oublier !
$this->entityManager->flush();Prévention
- Ajouter la vérification de persistance à la checklist de revue de code
- Considérer l'auto-flush dans une classe de base de service
### Checklist de Documentation
- [ ] Message de commit décrit le bug et la correction
- [ ] Tracker d'issues mis à jour avec la résolution
- [ ] Documentation liée mise à jour
- [ ] Entrée base de connaissances si pattern
---
## Procédures Hotfix
Pour les bugs critiques en production.
### Workflow Hotfix- Créer une branche hotfix depuis production
- Appliquer la correction minimale
- Tester en profondeur
- Déployer en production
- Merger vers main
### Étape par Étape
```bash
# 1. Créer la branche hotfix
git checkout production
git checkout -b hotfix/issue-123-echec-connexion
# 2. Appliquer la correction
# ... faire les changements ...
# 3. Écrire le test de régression
# ... ajouter le test ...
# 4. Vérifier
make test
/symfony:check-compliance
# 5. Commiter avec un message clair
git commit -m "fix(auth): résoudre l'échec critique de connexion après réinitialisation
HOTFIX pour problème de production.
Cause racine : Hash de mot de passe non persisté après réinitialisation.
Closes #123"
# 6. Créer la PR pour revue
gh pr create --base production --title "HOTFIX: Échec de connexion après réinitialisation"
# 7. Après merge, déployer
# ... processus de déploiement ...
# 8. Merger vers main
git checkout main
git merge hotfix/issue-123-echec-connexion
git push origin mainChecklist Hotfix
- [ ] Branche hotfix depuis production
- [ ] Correction minimale et ciblée uniquement
- [ ] Test de régression ajouté
- [ ] Tous les tests passent
- [ ] PR revue et approuvée
- [ ] Déployé en production
- [ ] Vérifié en production
- [ ] Mergé vers main
Exemple Complet
Parcourons la correction d'un bug réel.
Rapport de Bug
Issue #456 : Total de commande calculé incorrectement
Étapes pour reproduire :
1. Ajouter un article à 10,00€, quantité 3
2. Ajouter un article à 5,50€, quantité 2
3. Voir le panier
Attendu : Total = 41,00€ (30 + 11)
Réel : Total = 36,00€
Environnement : Production v2.3.1
Rapporté par : Support client
Priorité : HauteÉtape 1 : Reproduire
// Test local rapide
$order = new Order();
$order->addItem(new Item('A', 10.00), 3); // 30€
$order->addItem(new Item('B', 5.50), 2); // 11€
echo $order->getTotal(); // Affiche 36.00 - confirmé !Étape 2 : Diagnostiquer
@tdd-coach Aide-moi à trouver le bug dans le calcul du total
Le total devrait être 41,00 mais affiche 36,00
La différence est 5,00, exactement le prix d'un article B
Hypothèse : la quantité du second article n'est pas comptée ?L'investigation révèle :
// Bug trouvé dans Order::calculateTotal()
public function calculateTotal(): Money
{
$total = Money::zero();
foreach ($this->items as $item) {
// BUG : Utilise 1 au lieu de la quantité de l'article !
$total = $total->add($item->getPrice()->multiply(1));
}
return $total;
}Étape 3 : Écrire le Test de Régression
/**
* @test
* @see https://github.com/company/shop/issues/456
*
* Bug : Le total ignorait les quantités
*/
public function test_order_total_includes_all_quantities(): void
{
$order = new Order();
$order->addItem($this->createItem(10.00), 3); // 30€
$order->addItem($this->createItem(5.50), 2); // 11€
$total = $order->calculateTotal();
$this->assertEquals(41.00, $total->getAmount());
}
/**
* @test
* Cas limite : article unique avec quantité > 1
*/
public function test_single_item_quantity_multiplied(): void
{
$order = new Order();
$order->addItem($this->createItem(10.00), 5);
$this->assertEquals(50.00, $order->calculateTotal()->getAmount());
}Exécuter le test - confirme qu'il échoue.
Étape 4 : Corriger
public function calculateTotal(): Money
{
$total = Money::zero();
foreach ($this->items as $item) {
// Corrigé : Utilise la quantité réelle de l'article
$total = $total->add(
$item->getPrice()->multiply($item->getQuantity())
);
}
return $total;
}Étape 5 : Valider
# Le test de régression passe
./vendor/bin/phpunit --filter test_order_total
# Tous les tests passent
make test
# Vérification qualité
/symfony:check-compliance
# Score : 94/100 ✓Étape 6 : Documenter
git commit -m "fix(order): corriger le calcul du total pour inclure les quantités
Bug : Le total ignorait les quantités, utilisant toujours 1
Cause racine : multiply(1) codé en dur au lieu de multiply(quantity)
Correction : Utiliser getQuantity() de l'article dans le calcul
Closes #456
Tests de régression ajoutés :
- test_order_total_includes_all_quantities
- test_single_item_quantity_multiplied"Conseils de Prévention des Bugs
- Écrivez les tests d'abord : Le TDD prévient beaucoup de bugs
- Revue de code : Des yeux frais détectent les problèmes
- Analyse statique : Les outils trouvent les erreurs courantes
- Tests d'intégration : Détectent les bugs d'interaction
- Monitoring production : Détectez les problèmes tôt
