Pourquoi des tests « verts » ne sont-ils pas encore une victoire ?
\n\nImaginez : vous avez écrit une centaine de tests unitaires, ils passent tous avec un coche vert, le pipeline CI est heureux, le manager est satisfait. Mais un mois plus tard, une fonctionnalité critique tombe en production. Une histoire familière ? Le plus souvent, le problème vient du fait que nous testons les mauvais scénarios ou que nous sautons des branches entières de code.
\n\nLa couverture de code par les tests (code coverage) n'est pas simplement une métrique à la mode pour un rapport. C'est votre lampe de poche dans la pièce sombre de l'incertitude. Quand j'ai commencé à travailler avec C#, je pensais que 80 % de couverture était l'idéal. Mais j'ai ensuite compris : on peut avoir 100 % de couverture de lignes et pourtant passer à côté d'un bug dans la logique de branchement. C'est pourquoi aujourd'hui nous allons voir comment mesurer correctement la couverture en C#, quels outils aident réellement, et quelles métriques il faut suivre.
\n\nQu'est-ce que la couverture de code et pourquoi est-elle importante pour un développeur C# ?
\n\nEn termes simples, la couverture de code montre quel pourcentage du code source de votre application a été exécuté pendant l'exécution des tests. Si vous avez écrit un test qui appelle la méthode CalculateDiscount(), mais ne vérifie pas la branche if (isPremiumUser), alors cette branche reste « non couverte ».
Pour un développeur C#, la couverture est un indicateur de deux choses :
\n- \n
- Confiance dans le refactoring — peut-on modifier le code sans craindre de casser quelque chose ? \n
- Complétude des tests — n'avons-nous pas oublié les cas limites ? \n
Mais il y a une nuance importante : la couverture de code par les tests en C# ne garantit pas l'absence de bugs. Elle indique seulement que certaines lignes ont été exécutées. C'est pourquoi nous ne regardons pas simplement le pourcentage, mais les métriques spécifiques.
\n\nLes principales métriques de couverture de code dans .NET
\n\nLorsque vous lancez une analyse de couverture en C#, vous rencontrez plusieurs types de métriques. Analysons chacune d'elles avec un exemple de code réel.
\n\nLine Coverage (couverture de lignes)
\nLa métrique la plus simple. Elle compte combien de lignes de code ont été touchées par les tests. Exemple :
\n\npublic int Add(int a, int b)\n{\n if (a < 0) // ligne 1\n return 0; // ligne 2\n return a + b; // ligne 3\n}\n\nSi votre test appelle Add(5, 3), alors les lignes 1 et 3 seront exécutées. La ligne 2 restera non couverte. Line coverage affichera 66 % (2 lignes sur 3).
Branch Coverage (couverture de branchements)
\nUne métrique plus honnête. Elle prend en compte tous les chemins d'exécution possibles. Dans notre exemple, il y a deux chemins : quand a < 0 et quand ce n'est pas le cas. Si vous n'avez testé que le cas avec un nombre positif, Branch coverage sera de 50 %.
C'est précisément Branch coverage qui révèle souvent des « trous » dans les tests. Je recommande de viser 80 %+ sur cette métrique.
\n\nCyclomatic Complexity et son lien avec la couverture
\nBien que ce ne soit pas une métrique de couverture directe, la complexité cyclomatique montre combien de tests sont nécessaires pour une couverture complète. Plus la complexité d'une méthode est élevée, plus il faut de tests. Si vous voyez une méthode avec une complexité cyclomatique de 15 et une couverture de 90 % — il y a de fortes chances que vous ne testiez pas tous les scénarios.
\n\nOutils pour mesurer la couverture de code en C#
\n\nDans l'écosystème .NET, il existe plusieurs outils puissants. Je vais vous parler des trois plus populaires avec lesquels j'ai travaillé moi-même.
\n\nCoverlet — gratuit et intégré à .NET
\nSi vous utilisez .NET 6+, Coverlet est déjà disponible via NuGet. C'est mon outil préféré pour le CI/CD car il ne nécessite pas l'installation de programmes supplémentaires.
\n\nInstallation :
\ndotnet add package coverlet.msbuild\ndotnet add package coverlet.collector\n\nLancement avec rapport :
\ndotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover\n\nVous obtiendrez un fichier coverage.opencover.xml, qui peut être visualisé avec ReportGenerator :
dotnet tool install -g dotnet-reportgenerator-globaltool\nreportgenerat