Si vous deviez imposer un pourcentage minimum de couverture de code pour les tests unitaires, peut-être même comme exigence pour vous engager dans un référentiel, quel serait-il?
Veuillez expliquer comment vous êtes arrivé à votre réponse (puisque si tout ce que vous avez fait était de choisir un numéro, alors j'aurais pu le faire tout seul;)
unit-testing
code-coverage
code-metrics
santé mentale
la source
la source
Réponses:
Cette prose d'Alberto Savoia répond précisément à cette question (d'une manière bien amusante à cela!):
http://www.artima.com/forums/flat.jsp?forum=106&thread=204677
la source
La couverture du code est une mesure trompeuse si une couverture à 100% est votre objectif (au lieu de tester à 100% toutes les fonctionnalités).
Faites donc confiance à vous ou à vos développeurs pour être minutieux et parcourir tous les chemins à travers leur code. Soyez pragmatique et ne poursuivez pas la couverture magique à 100%. Si vous TDD votre code, vous devriez obtenir une couverture de 90% + en bonus. Utilisez la couverture de code pour mettre en évidence des morceaux de code que vous avez manqués (cela ne devrait pas se produire si vous TDD .. car vous n'écrivez du code que pour réussir un test. Aucun code ne peut exister sans son test partenaire.)
la source
La couverture du code est excellente, mais la couverture des fonctionnalités est encore meilleure. Je ne crois pas à couvrir chaque ligne que j'écris. Mais je crois en écrivant une couverture de test à 100% de toutes les fonctionnalités que je veux fournir (même pour les fonctionnalités extra cool que je suis venu avec moi-même et qui n'ont pas été discutées lors des réunions).
Je ne me soucie pas d'avoir du code qui n'est pas couvert par les tests, mais je me soucierais de refactoriser mon code et de finir par avoir un comportement différent. Par conséquent, une couverture de fonctionnalité à 100% est ma seule cible.
la source
La réponse acceptée fait un bon point - il n'y a pas un seul chiffre qui va avoir du sens comme standard pour chaque projet. Il y a des projets qui n'ont tout simplement pas besoin d'une telle norme. À mon avis, la réponse acceptée ne suffit pas à décrire comment on pourrait prendre cette décision pour un projet donné.
Je vais tenter de le faire. Je ne suis pas un expert en ingénierie de test et serais heureux de voir une réponse plus éclairée.
Quand définir les exigences de couverture du code
Premièrement, pourquoi voudriez-vous imposer une telle norme en premier lieu? En général, lorsque vous souhaitez introduire une confiance empirique dans votre processus. Qu'est-ce que j'entends par «confiance empirique»? Eh bien, le vrai objectif correct . Pour la plupart des logiciels, nous ne pouvons pas le savoir sur toutes les entrées, nous nous contentons donc de dire que le code est bien testé . C'est plus connu, mais c'est toujours une norme subjective: il sera toujours possible de débattre si vous l'avez ou non respecté. Ces débats sont utiles et devraient avoir lieu, mais ils révèlent également des incertitudes.
La couverture du code est une mesure objective: une fois que vous voyez votre rapport de couverture, il n'y a aucune ambiguïté quant à savoir si les normes ont été respectées sont utiles. Prouve-t-elle l'exactitude? Pas du tout, mais cela a une relation claire avec la qualité du test du code, ce qui est à notre tour notre meilleure façon d'augmenter la confiance dans son exactitude. La couverture du code est une approximation mesurable des qualités incommensurables dont nous nous soucions.
Quelques cas spécifiques où avoir une norme empirique pourrait ajouter de la valeur:
Quelles mesures utiliser
La couverture du code n'est pas une métrique unique; il existe plusieurs façons différentes de mesurer la couverture. Lequel vous pouvez définir une norme dépend de ce que vous utilisez pour satisfaire.
J'utiliserai deux mesures courantes comme exemples de cas où vous pourriez les utiliser pour définir des normes:
if
), les deux branches ont-elles été évaluées? Cela donne une meilleure idée de la couverture logique de votre code: combien de chemins possibles mon code peut-il avoir testés?Il existe de nombreuses autres mesures (la couverture de ligne est similaire à la couverture de relevé, mais donne des résultats numériques différents pour les relevés multilignes, par exemple; la couverture conditionnelle et la couverture de chemin sont similaires à la couverture de branche, mais reflètent une vue plus détaillée des permutations possibles de exécution de programme que vous pourriez rencontrer.)
Quel pourcentage exiger
Enfin, revenons à la question d'origine: si vous définissez des normes de couverture de code, quel devrait être ce nombre?
J'espère qu'il est clair à ce stade que nous parlons d'une approximation pour commencer, donc tout chiffre que nous choisirons sera intrinsèquement approximatif.
Quelques chiffres que l'on pourrait choisir:
Je n'ai pas vu de chiffres inférieurs à 80% dans la pratique, et j'ai du mal à imaginer un cas où l'on les fixerait. Le rôle de ces normes est d'accroître la confiance dans l'exactitude, et les chiffres inférieurs à 80% ne sont pas particulièrement inspirants. (Oui, c'est subjectif, mais encore une fois, l'idée est de faire le choix subjectif une fois lorsque vous définissez la norme, puis d'utiliser une mesure objective à l'avenir.)
Autres notes
Ce qui précède suppose que l'exactitude est le but. La couverture du code n'est qu'une information; il peut être pertinent pour d'autres objectifs. Par exemple, si vous êtes préoccupé par la maintenabilité, vous vous souciez probablement du couplage lâche, qui peut être démontré par la testabilité, qui à son tour peut être mesurée (dans certaines modes) par la couverture du code. Votre norme de couverture de code fournit donc une base empirique pour estimer également la qualité de la "maintenabilité".
la source
Ma couverture de code préférée est 100% avec un astérisque. L'astérisque vient parce que je préfère utiliser des outils qui me permettent de marquer certaines lignes comme des lignes qui "ne comptent pas". Si j'ai couvert 100% des lignes qui "comptent", j'ai terminé.
Le processus sous-jacent est:
De cette façon, si moi et mes collaborateurs ajoutons du nouveau code ou modifions les tests à l'avenir, il y a une ligne claire pour nous dire si nous avons raté quelque chose d'important - la couverture est tombée en dessous de 100%. Cependant, il offre également la flexibilité nécessaire pour gérer différentes priorités de test.
la source
// @codeCoverageIgnore
et elle sera exclue de la couverture.Je voudrais avoir une autre anectode sur la couverture des tests que je voudrais partager.
Nous avons un énorme projet dans lequel, sur Twitter, j'ai remarqué qu'avec 700 tests unitaires, nous n'avons que 20% de couverture de code .
Scott Hanselman a répondu avec des paroles de sagesse :
Encore une fois, cela revient à mon Testivus sur la réponse à la couverture de code . Combien de riz faut-il mettre dans le pot? Ça dépend.
la source
Pour un système bien conçu, où les tests unitaires ont guidé le développement depuis le début, je dirais que 85% est un nombre assez faible. Les petites classes conçues pour être testables ne devraient pas être difficiles à couvrir mieux que cela.
Il est facile de rejeter cette question avec quelque chose comme:
Certes, mais il y a quelques points importants à faire sur la couverture du code. D'après mon expérience, cette métrique est en fait très utile lorsqu'elle est utilisée correctement. Cela dit, je n'ai pas vu tous les systèmes et je suis sûr qu'il y en a des tonnes où il est difficile de voir une analyse de la couverture de code ajouter une valeur réelle. Le code peut sembler si différent et la portée du cadre de test disponible peut varier.
De plus, mon raisonnement concerne principalement des boucles de rétroaction de test assez courtes. Pour le produit que je développe, la boucle de rétroaction la plus courte est assez flexible, couvrant tout, des tests de classe à la signalisation inter-processus. Le test d'un sous-produit livrable prend généralement 5 minutes et pour une boucle de rétroaction aussi courte, il est en effet possible d'utiliser les résultats du test (et en particulier la mesure de couverture de code que nous examinons ici) pour rejeter ou accepter les validations dans le référentiel.
Lorsque vous utilisez la mesure de couverture de code, vous ne devez pas simplement avoir un pourcentage fixe (arbitraire) qui doit être respecté. À mon avis, cela ne vous donne pas les avantages réels de l'analyse de la couverture du code. Définissez plutôt les mesures suivantes:
Un nouveau code ne peut être ajouté que si nous n'allons pas au-dessus du LWM et si nous n'allons pas au-dessous du HWM. En d'autres termes, la couverture du code ne doit pas diminuer et le nouveau code doit être couvert. Remarquez comment je dis devrait et ne doit pas (expliqué ci-dessous).
Mais cela ne signifie-t-il pas qu'il sera impossible de nettoyer les vieux déchets bien testés dont vous n'avez plus besoin? Oui, et c'est pourquoi vous devez être pragmatique à propos de ces choses. Il y a des situations où les règles doivent être enfreintes, mais pour votre intégration quotidienne typique, mon expérience montre que ces mesures sont très utiles. Ils donnent les deux implications suivantes.
Le code testable est promu. Lors de l'ajout de nouveau code, vous devez vraiment faire un effort pour rendre le code testable, car vous devrez essayer de tout couvrir avec vos cas de test. Le code testable est généralement une bonne chose.
La couverture des tests pour le code hérité augmente avec le temps. Lorsque vous ajoutez du nouveau code et que vous ne pouvez pas le couvrir avec un cas de test, vous pouvez essayer de couvrir un code hérité à la place pour contourner la règle LWM. Cette triche parfois nécessaire donne au moins l'effet secondaire positif que la couverture du code hérité augmentera avec le temps, ce qui rend l'application apparemment stricte de ces règles assez pragmatique dans la pratique.
Et encore une fois, si la boucle de rétroaction est trop longue, il pourrait être complètement impossible de configurer quelque chose comme ça dans le processus d'intégration.
Je voudrais également mentionner deux autres avantages généraux de la mesure de couverture du code.
L'analyse de couverture de code fait partie de l'analyse de code dynamique (par opposition à l'analyse statique, c'est-à-dire Lint). Les problèmes rencontrés lors de l'analyse de code dynamique (par des outils tels que la famille purify, http://www-03.ibm.com/software/products/en/rational-purify-family ) sont des choses comme les lectures de mémoire non initialisées (UMR), fuites de mémoire, etc. Ces problèmes ne peuvent être trouvés que si le code est couvert par un cas de test exécuté . Le code qui est le plus difficile à couvrir dans un cas de test est généralement les cas anormaux du système, mais si vous voulez que le système échoue gracieusement (c.-à-d. Trace d'erreur au lieu de planter), vous voudrez peut-être faire un effort pour couvrir les cas anormaux dans l'analyse de code dynamique également. Avec juste un peu de malchance, un UMR peut conduire à une faute de segment ou pire.
Les gens sont fiers de garder 100% pour le nouveau code, et les gens discutent des problèmes de test avec une passion similaire à d'autres problèmes d'implémentation. Comment cette fonction peut-elle être écrite de manière plus testable? Comment feriez-vous pour essayer de couvrir ce cas anormal, etc.
Et un négatif, pour être complet.
la source
Si c'était un monde parfait, 100% du code serait couvert par des tests unitaires. Cependant, comme ce n'est PAS un monde parfait, c'est une question de temps pour vous. En conséquence, je recommande de se concentrer moins sur un pourcentage spécifique et de se concentrer davantage sur les domaines critiques. Si votre code est bien écrit (ou au moins un fac-similé raisonnable de celui-ci), il devrait y avoir plusieurs points clés où les API sont exposées à un autre code.
Concentrez vos efforts de test sur ces API. Assurez-vous que les API sont 1) bien documentées et 2) que des cas de test écrits correspondent à la documentation. Si les résultats attendus ne correspondent pas aux documents, alors vous avez un bogue dans votre code, votre documentation ou vos cas de test. Tout cela est bon à examiner.
Bonne chance!
la source
De nombreux magasins n'évaluent pas les tests, donc si vous êtes au-dessus de zéro au moins, il y a une certaine appréciation de la valeur - donc sans doute non-nul n'est pas mauvais car beaucoup sont toujours nuls.
Dans le monde .Net, les gens citent souvent 80% comme raison. Mais ils disent cela au niveau de la solution. Je préfère mesurer au niveau du projet: 30% pourrait être bien pour le projet d'interface utilisateur si vous avez du sélénium, etc. ou des tests manuels, 20% pour le projet de couche de données pourrait être bien, mais 95% + pourrait être tout à fait réalisable pour l'entreprise couche de règles, si pas entièrement nécessaire. Ainsi, la couverture globale peut être, disons, de 60%, mais la logique métier critique peut être beaucoup plus élevée.
J'ai également entendu ceci: aspirer à 100% et vous atteindrez 80%; mais aspirez à 80% et vous atteindrez 40%.
En résumé: appliquez la règle 80:20 et laissez le nombre de bogues de votre application vous guider.
la source
La couverture du code n'est qu'une autre mesure. En soi, il peut être très trompeur (voir www.thoughtworks.com/insights/blog/are-test-coverage-metrics-overrated ). Votre objectif ne doit donc pas être d'atteindre une couverture de code à 100% mais plutôt de vous assurer de tester tous les scénarios pertinents de votre application.
la source
85% serait un bon point de départ pour les critères d'enregistrement.
J'aurais probablement choisi une variété de barres plus élevées pour les critères d'expédition - en fonction de la criticité des sous-systèmes / composants testés.
la source
J'utilise cobertura, et quel que soit le pourcentage, je recommanderais de maintenir à jour les valeurs de la tâche cobertura-check. Au minimum, continuez à augmenter la totalisation et la répartition totale juste en dessous de votre couverture actuelle, mais ne baissez jamais ces valeurs. Liez également la propriété Ant build failure à cette tâche. Si la construction échoue en raison d'un manque de couverture, vous connaissez le code ajouté de quelqu'un mais ne l'avez pas testé. Exemple:
la source
Lorsque je pense que mon code n'est pas suffisamment testé à l'unité et que je ne sais pas quoi tester ensuite, j'utilise la couverture pour m'aider à décider quoi tester ensuite.
Si j'augmente la couverture dans un test unitaire - je sais que ce test unitaire vaut quelque chose.
Cela vaut pour le code qui n'est pas couvert, 50% couvert ou 97% couvert.
la source
Je préfère faire BDD, qui utilise une combinaison de tests d'acceptation automatisés, éventuellement d'autres tests d'intégration et des tests unitaires. La question pour moi est de savoir quelle devrait être la couverture cible de la suite de tests automatisée dans son ensemble.
Cela mis à part, la réponse dépend de votre méthodologie, de votre langue et de vos outils de test et de couverture. Lorsque vous effectuez TDD en Ruby ou Python, il n'est pas difficile de maintenir une couverture à 100%, et cela en vaut la peine. Il est beaucoup plus facile de gérer une couverture à 100% qu'une couverture à 90%. Autrement dit, il est beaucoup plus facile de combler les lacunes de couverture au fur et à mesure qu'elles apparaissent (et lorsque vous faites bien le TDD, les lacunes de couverture sont rares et valent généralement la peine) que de gérer une liste des lacunes de couverture que vous n'avez pas pu contourner et que vous manquez de couverture. régressions dues à votre arrière-plan constant de code découvert.
La réponse dépend également de l'historique de votre projet. Je n'ai trouvé que ce qui précède pratique dans les projets gérés de cette façon depuis le début. J'ai considérablement amélioré la couverture des grands projets hérités, et cela en valait la peine, mais je n'ai jamais trouvé pratique de revenir en arrière et de combler toutes les lacunes de couverture, car l'ancien code non testé n'est pas suffisamment bien compris pour le faire correctement et rapidement.
la source
Si vous effectuez des tests unitaires depuis un bon moment, je ne vois aucune raison pour que cela n'approche pas de 95% +. Cependant, au minimum, j'ai toujours travaillé avec 80%, même lorsqu'il était nouveau dans les tests.
Ce nombre ne doit inclure que du code écrit dans le projet (exclut les frameworks, plugins, etc.) et peut-être même exclut certaines classes composées entièrement de code écrit d'appels à du code extérieur. Ce type d'appel doit être moqué / tronqué.
la source
De manière générale, parmi les nombreux articles sur les meilleures pratiques en matière d'excellence en ingénierie que j'ai lus, 80% pour le nouveau code dans les tests unitaires est le point qui donne le meilleur rendement. Aller au-dessus de ce CC% donne une quantité inférieure de défauts pour la quantité d'effort exercée. Il s'agit d'une meilleure pratique utilisée par de nombreuses grandes sociétés.
Malheureusement, la plupart de ces résultats sont internes aux entreprises, il n'y a donc pas de littérature publique sur laquelle je puisse vous indiquer.
la source
La couverture du code est excellente, mais seulement tant que les avantages que vous en retirez l'emportent sur le coût / l'effort de sa réalisation.
Nous travaillons à une norme de 80% depuis un certain temps, mais nous venons de prendre la décision de l'abandonner et de nous concentrer davantage sur nos tests. Se concentrer sur la logique métier complexe, etc.,
Cette décision a été prise en raison du temps croissant que nous avons passé à rechercher la couverture du code et à maintenir les tests unitaires existants. Nous pensions que nous étions arrivés au point où l'avantage que nous obtenions de notre couverture de code était jugé inférieur à l'effort que nous devions déployer pour y parvenir.
la source
Réponse courte: 60-80%
Réponse longue: je pense que cela dépend totalement de la nature de votre projet. Je commence généralement un projet en testant à l'unité chaque pièce pratique. À la première "version" du projet, vous devriez avoir un assez bon pourcentage de base basé sur le type de programmation que vous faites. À ce stade, vous pouvez commencer à «appliquer» une couverture de code minimale.
la source
Découvrez Crap4j . C'est une approche légèrement plus sophistiquée que la couverture de code simple. Il combine des mesures de couverture de code avec des mesures de complexité, puis vous montre quel code complexe n'est pas actuellement testé.
la source
Ma réponse à cette énigme est d'avoir une couverture en ligne de 100% du code que vous pouvez tester et une couverture en ligne de 0% du code que vous ne pouvez pas tester.
Ma pratique actuelle en Python consiste à diviser mes modules .py en deux dossiers: app1 / et app2 / et lors de l'exécution des tests unitaires, calculer la couverture de ces deux dossiers et vérifier visuellement (je dois automatiser cela un jour) que app1 a une couverture de 100% et app2 a une couverture de 0%.
Lorsque / si je trouve que ces chiffres diffèrent de la norme, j'étudie et modifie la conception du code afin que la couverture soit conforme à la norme.
Cela signifie que je peux recommander d'atteindre une couverture de ligne à 100% du code de la bibliothèque.
Je passe également en revue de temps en temps app2 / pour voir si je pouvais tester n'importe quel code là-bas, et si je peux le déplacer dans app1 /
Maintenant, je ne suis pas trop inquiet de la couverture globale car cela peut varier énormément en fonction de la taille du projet, mais en général, j'ai vu 70% à plus de 90%.
Avec python, je devrais être en mesure de concevoir un test de fumée qui pourrait exécuter automatiquement mon application tout en mesurant la couverture et, espérons-le, obtenir un agrégat de 100% en combinant le test de fumée avec des chiffres les plus faibles.
la source
Voir la couverture sous un autre angle: un code bien écrit avec un flux de contrôle clair est le plus facile à couvrir, le plus facile à lire et généralement le moins buggé. En écrivant le code avec la clarté et la couvrabilité à l'esprit, et en écrivant les tests unitaires en parallèle avec le code, vous obtenez les meilleurs résultats à mon humble avis.
la source
À mon avis, la réponse est "Cela dépend du temps dont vous disposez". J'essaie d'atteindre 100% mais je ne fais pas d'histoires si je ne l'obtiens pas avec le temps dont je dispose.
Lorsque j'écris des tests unitaires, je porte un chapeau différent de celui que je porte lors du développement du code de production. Je pense à ce que le code testé prétend faire et quelles sont les situations qui peuvent le casser.
Je respecte généralement les critères ou règles suivants:
Que le test unitaire devrait être une forme de documentation sur le comportement attendu de mes codes, c'est-à-dire. la sortie attendue étant donnée une certaine entrée et les exceptions qu'elle peut lever que les clients peuvent vouloir attraper (ce que les utilisateurs de mon code devraient savoir?)
Que le test unitaire devrait m'aider à découvrir les conditions que je n'aurais peut-être pas encore imaginées. (Comment rendre mon code stable et robuste?)
Si ces deux règles ne produisent pas une couverture à 100%, qu'il en soit ainsi. Mais une fois, j'ai le temps, j'analyse les blocs et les lignes découverts et détermine s'il y a encore des cas de test sans tests unitaires ou si le code doit être refactorisé pour éliminer les codes inutiles.
la source
Cela dépend beaucoup de votre application. Par exemple, certaines applications se composent principalement de code GUI qui ne peut pas être testé à l'unité.
la source
Je ne pense pas qu'il puisse y avoir une telle règle N / B.
Le code doit être révisé, en accordant une attention particulière aux détails critiques.
Cependant, s'il n'a pas été testé, il a un bug!
la source
Selon la criticité du code, entre 75% et 85% est une bonne règle de base. Le code d'expédition doit certainement être testé de manière plus approfondie que dans les services publics, etc.
la source
Cela doit dépendre de la phase du cycle de vie de développement de votre application dans laquelle vous vous trouvez.
Si vous êtes au développement depuis un certain temps et que vous avez déjà beaucoup de code implémenté et que vous réalisez maintenant que vous devez penser à la couverture du code, vous devez vérifier votre couverture actuelle (si elle existe), puis utiliser cette ligne de base pour définir des jalons à chaque sprint (ou une augmentation moyenne sur une période de sprints), ce qui signifie assumer la dette de code tout en continuant à fournir de la valeur à l'utilisateur final (du moins d'après mon expérience, l'utilisateur final ne se soucie pas du tout si vous avez augmenté le test couverture s'ils ne voient pas de nouvelles fonctionnalités).
Selon votre domaine, il n'est pas déraisonnable de viser 95%, mais je dois dire qu'en moyenne, vous allez examiner un cas moyen de 85% à 90%.
la source
Je pense que le meilleur symptôme d'une couverture de code correcte est que la quantité de problèmes concrets que les tests unitaires aident à résoudre correspond raisonnablement à la taille du code de tests unitaires que vous avez créé.
la source
Je pense que ce qui importe le plus, c'est de savoir quelle est la tendance de la couverture au fil du temps et de comprendre les raisons des changements dans la tendance. Que vous considériez les changements de tendance comme bons ou mauvais dépendra de votre analyse de la raison.
la source
Nous visions> 80% jusqu'à il y a quelques jours, mais après avoir utilisé beaucoup de code généré, nous ne nous soucions pas du pourcentage d'âge, mais faisons en sorte que le réviseur prenne un appel sur la couverture requise.
la source
D'après la publication de Testivus, je pense que le contexte de réponse devrait être le deuxième programmeur. Cela dit, d'un point de vue pratique, nous avons besoin de paramètres / objectifs à atteindre. Je considère que cela peut être "testé" dans un processus Agile en analysant le code dont nous avons l'architecture, les fonctionnalités (user stories), puis en arriver à un certain nombre. Sur la base de mon expérience dans le domaine des télécommunications, je dirais que 60% est une bonne valeur à vérifier.
la source