Le code coverage, c’est le pourcentage de votre code qui s’exécute quand vous lancez vos tests. Ni plus, ni moins. Et c’est bien le problème : beaucoup de développeurs confondent "mon code est exécuté" avec "mon code est testé".
Le code coverage, c’est quoi ?
Quand vous lancez vos tests unitaires ou fonctionnels, un outil de couverture enregistre quelles lignes passent et lesquelles non. 80% de couverture, ça veut dire que 20% de votre code n’a jamais été touché.
Sur un projet Python, Coverage.py fait ça bien. Vous lancez vos tests, il sort un rapport, vous voyez les trous. Simple.
Le piège, c’est qu’un test peut très bien exécuter du code sans rien vérifier. J’ai vu des projets à 95% de couverture où la moitié des tests n’avaient aucune assertion. Le dashboard était tout vert, et les bugs passaient quand même en production.
Les différentes mesures
Il y a plusieurs façons de compter, et elles ne racontent pas la même histoire.
Couverture des lignes (line coverage)
La plus répandue. Combien de lignes ont été exécutées ? C’est ce que la plupart des outils affichent par défaut. Une application React testée avec Jest peut afficher 90% ici, et pourtant avoir des if/else entiers qui n’ont jamais été testés dans le cas "else".
Couverture des branches (branch coverage)
Celle-là est plus intéressante. Elle vérifie que chaque if/else, chaque switch, a été emprunté dans tous ses cas. Sur du code de paiement, ça fait la différence entre "le validateur a tourné" et "on sait ce qui se passe quand la carte est refusée".
Couverture des chemins (path coverage)
Toutes les combinaisons possibles de branches dans une fonction. Le plus complet en théorie. En pratique, une fonction avec 10 conditions a 1024 chemins possibles, donc on oublie vite le 100%.
Couverture des fonctions (function coverage)
Est-ce que chaque fonction a été appelée au moins une fois ? C’est le minimum. Pratique pour repérer du code mort, mais ça ne vous dit rien sur ce qui se passe à l’intérieur.
À quoi ça sert concrètement ?
Attraper les bugs avant la prod
C’est l’argument évident. Si votre composant d’authentification n’est pas testé, vous le découvrirez le jour où un utilisateur ne pourra plus se connecter. Pas idéal.
Voir ce que personne ne comprend
Les zones non couvertes, ce sont souvent celles que l’équipe évite. Personne ne les teste parce que personne ne sait trop ce qu’elles font. Le rapport de couverture rend ça visible. Des routes API à 0% de couverture ? Soit elles sont inutiles, soit elles sont dangereuses. Dans les deux cas, il faut s’en occuper.
Refactorer sans prier
Quand un module est bien couvert, vous pouvez le réécrire en sachant que vos tests vous préviendront si vous cassez quelque chose. Sans ça, chaque refacto est un lancer de dés.
Mise en place avec Django
Trois commandes et c'est fait.
pip install coverageLancez vos tests avec la mesure activée :
coverage run manage.py testEt consultez le résultat :
coverage reportPour un rapport HTML où vous pouvez naviguer fichier par fichier :
coverage htmlOuvrez htmlcov/index.html dans votre navigateur.

Ce que le coverage ne vous dit pas
Le coverage a un angle mort structurel : il mesure ce qui tourne, pas ce qui est vérifié. Un test qui appelle une fonction sans vérifier sa valeur de retour, ça compte dans les stats. Ça ne compte pas dans la réalité.
En pratique :
- Un test qui vérifie que le prix TTC avec 15% de remise renvoie bien 42,50€, c’est un vrai test. Un test qui appelle
calculer_prix()et ne regarde pas le résultat, c’est du remplissage. - Mettez le paquet sur ce qui fait vraiment mal quand ça casse. L’authentification, les paiements, le chiffrement. Un module de paiement couvert à moitié, c’est un problème qui attend son moment.
- Pas la peine de viser 100% sur un fichier de config ou un script de migration. Gardez votre énergie pour le code qui a des conséquences quand il se trompe.
Le coverage, c’est une carte. Ça vous montre le terrain. Mais c’est vous qui décidez où marcher.




