Niveau 08 — Tests et bonnes pratiques
Objectif du niveau
À la fin de ce niveau, tu sais écrire des tests automatisés avec pytest : installer l'outil, écrire des fonctions test_* avec assert, couvrir les cas limites, et lancer la suite après chaque modification. Tu sais aussi rendre un projet présentable et maintenable : structure de dossiers propre, noms explicites, fonctions courtes, docstrings, un README utile, et des commentaires qui expliquent le pourquoi plutôt que de paraphraser le code. Tu sais enfin refactorer : améliorer du code existant sans changer son comportement — les tests servant de filet.
Prérequis
- Niveau 07 — au moins trois projets terminés : ce niveau refactore et teste TON code existant, pas des exemples jouets.
- Niveau 04 — fonctions avec
return: on ne peut tester automatiquement que ce qui renvoie des valeurs (les fonctions qui ne font queprintsont intestables — on va justement les refactorer). - Niveau 05 — exceptions (tester qu'une erreur est bien levée) et modules (structure de projet).
- Notions clés :
returnvsprint,raise, imports, terminal.
Durée indicative et avertissement honnête
2 à 3 semaines à raison de 30–60 min par jour.
Techniquement, ce niveau est l'un des plus abordables : assert resultat == attendu n'a rien de sorcier, et pytest s'installe en une commande. La vraie difficulté est ailleurs : elle est culturelle. Écrire des tests semble d'abord une perte de temps (« mon code marche, je l'ai essayé »), et refactorer du code qui fonctionne semble du zèle. Le déclic arrive la première fois qu'un test attrape une régression que tu n'aurais jamais vue — le niveau est construit pour provoquer ce moment tôt. Autre friction honnête : tester du code qui fait input() et print() partout est pénible ; tu vas devoir restructurer tes projets du niveau 07 pour séparer calcul et affichage, et c'est un vrai travail.
Leçons prévues
Chaque leçon suivra le template 17 sections (lessons/TEMPLATE_LECON.md).
| N° | Titre | Notions couvertes | Statut |
|---|---|---|---|
| 08-1 | Structure propre et nommage | Arborescence type d'un petit projet, noms de variables/fonctions/modules explicites (conventions PEP 8 essentielles), fonctions courtes à responsabilité unique, séparer calcul et affichage (préparer la testabilité) | ✅ Disponible |
| 08-2 | pytest — premiers tests | Installer pytest (pip install), fichiers test_*.py, fonctions test_*, assert, lancer pytest et lire son rapport (le point vert, le F, le diff d'assertion), tester une fonction pure | ✅ Disponible |
| 08-3 | Cas limites et tests d'exceptions | Choisir ses cas de test (nominal, limites, entrées vides, valeurs extrêmes), pytest.raises pour tester qu'une exception est levée, organiser plusieurs tests par fonction, le réflexe « bug trouvé = test ajouté » | ✅ Disponible |
| 08-4 | Refactoring, docstrings et README | Refactorer sous protection des tests (renommer, extraire une fonction, supprimer un doublon), docstrings utiles (quoi/paramètres/retour), commentaires pourquoi vs bruit, écrire le README d'un projet (installation, usage, exemple) | ✅ Disponible |
Pièges et erreurs emblématiques du niveau
- Tester seulement le cas facile :
test_addition_2_plus_2et rien d'autre. Les bugs vivent dans les cas limites : liste vide, zéro, négatif, chaîne vide, fichier absent. - Des fonctions intestables : tout passe par
input()/print(), rien nereturn. Symptôme d'un défaut de conception hérité — le refactoring de la leçon 08-1 s'attaque exactement à ça. assertsans comparaison utile :assert f(x)au lieu deassert f(x) == attendu— le test passe pour de mauvaises raisons.- Refactorer ET modifier le comportement en même temps : impossible de savoir si le test rouge vient du refactor ou du changement. Une chose à la fois.
- Commentaires qui paraphrasent :
i += 1 # incrémente i. Du bruit qui vieillit mal ; le commentaire utile explique un choix, pas une syntaxe. ModuleNotFoundErroren lançant pytest : tests lancés du mauvais dossier, ou structure de projet bancale — retour du piège du niveau 05.
Mini-projets du niveau
Fiches détaillées dans /projects.
- Rétro-tester le gestionnaire de tâches — reprendre le projet 07-2, séparer calcul/affichage, écrire une suite de tests, refactorer sous filet.
- Kata testé en TDD léger — écrire les tests AVANT le code sur un problème de manipulation de texte, en cycle rouge → vert.
- README + docstrings du meilleur projet — rendre un projet du niveau 07 présentable : structure, docstrings, README complet, comme si un inconnu devait l'installer.
Critères de sortie
- Je sais installer pytest et lancer une suite de tests depuis le terminal.
- Je sais écrire un fichier de tests avec plusieurs
test_*et desassertpertinents, sans modèle. - Pour une fonction donnée, je sais lister ses cas limites AVANT d'écrire les tests.
- Je sais tester qu'une fonction lève bien l'exception attendue avec
pytest.raises. - Je sais lire un rapport pytest en échec et remonter à la ligne fautive.
- Je sais refactorer (renommer, extraire une fonction) sans changer le comportement, tests verts avant et après.
- Je sais écrire une docstring utile et un README qui permet à quelqu'un d'autre de lancer mon projet.
- Je sais justifier chaque commentaire de mon code — ou le supprimer.
Commit de fin de niveau
git add lessons/level-08-tests-bonnes-pratiques
git commit -m "exercises: complete level 08 (testing and good practices)"