Déclencheurs
- tdd
- test driven development
- test first
- write tests
- red green refactor
- test driven
- write test first
- failing test
- test before code
- strict testing
Instructions
Le cycle Red-Green-Refactor
Vous DEVEZ suivre ce cycle exact pour chaque fonctionnalité :
Étape 1 : RED — Écrire un test qui échoue
Avant d'écrire DU CODE d'implémentation, écrivez un test qui :
- Teste le comportement spécifique que vous êtes sur le point d'implémenter
- Est clair sur ce qu'il attend (valeurs exactes, pas des assertions vagues)
- ÉCHOUE quand vous l'exécutez (parce que le code n'existe pas encore)
# Exécutez le test et VÉRIFIEZ qu'il échoue
shell_execute: pytest tests/test_feature.py -v
# Attendu : FAILED (red)
Si le test réussit sans implémentation, votre test est mauvais. Supprimez-le et écrivez un meilleur test qui teste vraiment le nouveau comportement.
Étape 2 : GREEN — Écrire le code minimal pour passer
Écrivez le code MINIMUM nécessaire pour que le test passe. Pas plus.
Règles :
- Écrivez uniquement du code qui fait passer le test qui échoue
- N'ajoutez pas de fonctionnalités que le test ne couvre pas
- N'optimisez pas encore
- Ne gérez pas les cas limites que le test ne teste pas
- Codez les valeurs en dur si c'est tout ce que le test exige
# Exécutez le test et VÉRIFIEZ qu'il réussit
shell_execute: pytest tests/test_feature.py -v
# Attendu : PASSED (green)
Étape 3 : REFACTOR — Nettoyer pendant le green
Maintenant que le test passe, améliorez le code :
- Supprimez les doublons
- Améliorez les noms
- Extrayez des fonctions/classes
- Optimisez si nécessaire
Après CHAQUE changement, réexécutez le test :
shell_execute: pytest tests/test_feature.py -v
# Attendu : toujours PASSED (green)
Si le test échoue pendant le refactoring, annulez et essayez un changement plus petit.
Règles critiques
-
N'ÉCRIVEZ JAMAIS l'implémentation avant le test. Si vous vous surprenez à écrire une fonction avant son test, ARRÊTEZ. Supprimez la fonction. Écrivez d'abord le test.
-
NE SAUTEZ JAMAIS l'étape RED. Vous devez observer l'échec du test avant d'écrire l'implémentation. Cela vérifie que le test teste vraiment quelque chose.
-
Un test à la fois. N'écrivez pas 10 tests puis l'implémentation. Écrivez UN test, faites-le passer, puis écrivez le test suivant.
-
Les tests doivent être spécifiques.
assert result is not Nonen'est pas un test.assert result == {"status": "ok", "count": 3}est un test. -
Exécutez les tests après CHAQUE changement. Pas après 5 changements. Après chaque changement unique. La suite de tests est votre filet de sécurité — utilisez-la constamment.
-
Si vous cassez les tests existants, corrigez-les D'ABORD. Ne continuez pas à ajouter des fonctionnalités avec des tests cassés en arrière-plan.
Organisation du fichier de test
project/
src/
feature.py # Implémentation
tests/
test_feature.py # Tests pour feature.py
conftest.py # Fixtures partagées
- Le fichier de test reflète le fichier source :
src/auth.py->tests/test_auth.py - Une fonction de test par comportement, pas par méthode
- Utilisez des noms explicites :
test_login_with_invalid_password_returns_401
Modèles de test courants
Arrange-Act-Assert :
def test_user_creation():
# Arrange
data = {"name": "Alice", "email": "alice@example.com"}
# Act
user = create_user(data)
# Assert
assert user.name == "Alice"
assert user.email == "alice@example.com"
assert user.id is not None
Tester les exceptions :
def test_invalid_email_raises():
with pytest.raises(ValueError, match="invalid email"):
create_user({"name": "Alice", "email": "not-an-email"})
Tester les effets secondaires :
def test_send_welcome_email(mocker):
mock_send = mocker.patch("app.email.send")
create_user({"name": "Alice", "email": "alice@example.com"})
mock_send.assert_called_once_with("alice@example.com", subject="Welcome!")
Commandes de framework
| Langage | Exécuter les tests | Mode surveillance |
|---|---|---|
| Python | pytest -v |
pytest-watch |
| JavaScript | npm test |
npm test -- --watch |
| TypeScript | npx jest --verbose |
npx jest --watch |
| Rust | cargo test |
cargo watch -x test |
| Go | go test ./... |
gotestsum --watch |
Outils à utiliser
shell_execute— Exécuter les commandes de testfile_write/file_patch— Écrire les fichiers de test et l'implémentationfile_read— Lire le code existant pour comprendre ce qu'il faut testerself_read_source— Explorer la structure du projet
Quand NE PAS utiliser TDD
- Scripts jetables ou explorations ponctuelles
- Fichiers de configuration
- Contenu statique (HTML, CSS, markdown)
- Quand l'utilisateur dit explicitement « skip tests » ou « no tests needed »
Pour tout le reste : Red. Green. Refactor. À chaque fois.
Vérifier
- La suite de tests a été réellement exécutée et le code de sortie/résultat est capturé dans la transcription, pas seulement rédigée
- Les nombres de réussite/échec sont rapportés en chiffres (p. ex. « 42 réussis, 0 échoués »), pas « tous les tests réussissent »
- Les nouveaux tests couvrent au moins un cas négatif/limite en plus du cas nominal ; les cas sont énumérés
- Le delta de couverture ou les modules affectés sont rapportés quand le projet suit la couverture ; un nombre de base est cité
- Pour les tests instables ou sensibles au timing, la exécution a été répétée au moins 3 fois et le taux de réussite est rapporté
- Tous les tests ignorés ou xfail introduits sont énumérés avec une raison et un lien issue/TODO