Question Qu'est-ce qu'une couverture de code raisonnable% pour les tests unitaires (et pourquoi)? [fermé]


Si vous deviez imposer un pourcentage minimum de couverture de code pour les tests unitaires, peut-être même pour vous engager dans un référentiel, ce serait quoi?

Veuillez expliquer comment vous êtes arrivé à votre réponse (puisque si tout ce que vous faisiez était de choisir un numéro, alors j'aurais pu le faire tout seul)


491
2017-09-18 04:25


origine


Réponses:


Cette prose d'Alberto Savoia répond justement à cette question (d'une manière joliment amusante!):

http://www.artima.com/forums/flat.jsp?forum=106&thread=204677

Testivus sur la couverture de test

Tôt un matin, un programmeur a demandé   le grand maître:

"Je suis prêt à écrire des tests unitaires. Quelle couverture de code dois-je viser?   pour?"

Le grand maître a répondu:

"Ne vous inquiétez pas de la couverture, écrivez juste de bons tests."

Le programmeur sourit, s'inclina et   la gauche.

...

Plus tard ce jour-là, un deuxième programmeur   posé la même question.

Le grand maître montra un pot de   l'eau bouillante et a déclaré:

"Combien de grains de riz dois-je mettre dans ce pot?"

Le programmeur, perplexe,   a répondu:

"Comment puis-je vous le dire? Cela dépend du nombre de personnes dont vous avez besoin   nourrir, comment ils sont affamés, quels autres   la nourriture que vous servez, combien de riz   vous avez disponible, et ainsi de suite. "

"Exactement", dit le grand maître.

Le deuxième programmeur sourit, s'inclina,   et gauche.

...

Vers la fin de la journée, un troisième   programmeur est venu et a demandé la même   question sur la couverture du code.

"Quatre-vingt pour cent et rien de moins!" Répondit le maître d'une voix sévère,   frappant son poing sur la table.

Le troisième programmeur sourit, s'inclina,   et gauche.

...

Après cette dernière réponse, un jeune   apprenti a approché le grand   maîtriser:

"Grand maître, aujourd'hui je vous ai entendu répondre à la même question à propos de   couverture de code avec trois différents   réponses. Pourquoi?"

Le grand maître se leva de son   chaise:

"Viens prendre du thé frais avec moi et parlons-en."

Après qu'ils ont rempli leurs tasses avec   fumer du thé vert chaud, le grand   maître a commencé à répondre:

"Le premier programmeur est nouveau et commence à tester.   En ce moment il a beaucoup de code et pas de   tests. Il a un long chemin à parcourir;   en se concentrant sur la couverture du code en ce moment   serait déprimant et tout à fait inutile.   Il vaut mieux juste s'habituer à   écrire et exécuter des tests. Il peut   se soucier de la couverture plus tard. "

"Le second programmeur, d'autre part, est assez expérimenté à la fois   à la programmation et aux tests. Quand je   répondit en lui demandant combien de grains   de riz je devrais mettre dans un pot, je   l'a aidée à réaliser que la quantité de   les tests nécessaires dépendent d'un nombre   des facteurs, et elle sait ceux   facteurs mieux que moi - c'est elle   code après tout. Il n'y a pas un seul,   simple, répondre, et elle est assez intelligente   pour gérer la vérité et travailler avec   cette."

"Je vois", dit le jeune apprenti,   "Mais s'il n'y a pas un simple simple   répondre, alors pourquoi avez-vous répondu à la   troisième programmeur 'Quatre-vingt pour cent et   pas moins'?"

Le grand maître a ri si fort et   fort que son ventre, la preuve qu'il   bu plus que du thé vert,   floppé de haut en bas.

"Le troisième programmeur ne veut que des réponses simples - même quand il y a   pas de réponses simples ... et ne le fait pas   suis-les quand même. "

Le jeune apprenti et le grisonnant   grand maître a fini de boire leur   thé dans un silence contemplatif.


1097
2017-09-18 04:30



La couverture de code est une mesure trompeuse si votre objectif est la couverture à 100% (au lieu de tester à 100% toutes les fonctionnalités).

  • Vous pourriez obtenir 100% en frappant toutes les lignes une fois. Cependant, vous pourriez toujours manquer de tester une séquence particulière (chemin logique) dans laquelle ces lignes sont touchées.
  • Vous ne pouvez pas obtenir un 100%, mais avez quand même testé tous vos chemins de code utilisés à 80% / freq. Avoir des tests qui testent chaque "jet ExceptionTypeX" ou un programme de protection défensive similaire que vous avez mis en place est un plaisir de ne pas avoir un "must have"

Alors faites confiance à vous ou à vos développeurs pour être minutieux et couvrir chaque chemin à travers leur code. Soyez pragmatique et ne poursuivez pas la couverture magique à 100%. Si vous définissez votre code, vous devriez obtenir une couverture de 90% + en bonus. Utilisez la couverture de code pour mettre en évidence les morceaux de code que vous avez manqués (cela ne devrait pas se produire si vous TDD si vous écrivez du code pour effectuer un test. Aucun code ne peut exister sans son test partenaire).


72
2017-09-18 04:33



La couverture de code est excellente, mais la couverture de fonctionnalité est encore meilleure. Je ne crois pas à couvrir chaque ligne que j'écris. Mais je crois en l'écriture d'une couverture de test à 100% de toutes les fonctionnalités que je veux fournir (même pour les fonctionnalités supplémentaires que je suis venu avec moi et qui n'ont pas été discutées lors des réunions).

Je ne m'inquiète pas d'avoir un 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, la couverture de 100% des fonctionnalités est ma seule cible.


44
2018-04-27 22:56



La réponse acceptée fait un bon point: il n'y a pas un seul chiffre qui puisse avoir du sens en tant que norme pour chaque projet. Il y a des projets qui n'ont pas besoin d'une telle norme. Lorsque la réponse acceptée est insuffisante, à mon avis, c'est en décrivant comment on pourrait prendre cette décision pour un projet donné.

Je vais essayer de le faire. Je ne suis pas un expert en ingénierie de test et je serais heureux de voir une réponse plus éclairée.

Quand définir les exigences de couverture de code

Premièrement, pourquoi voudriez-vous imposer une telle norme en premier lieu? En général, lorsque vous voulez introduire une confiance empirique dans votre processus. Qu'est-ce que je veux dire par "confiance empirique"? Eh bien, le véritable objectif exactitude. 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é. Ceci est plus facile à connaître, mais reste une norme subjective: il sera toujours ouvert de débattre si vous l'avez rencontré ou non. Ces débats sont utiles et devraient se produire, mais ils exposent également l'incertitude.

Couverture de 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. Est-ce que cela prouve la rectitude? Pas du tout, mais il a un lien évident avec la qualité du test du code, ce qui est notre meilleur moyen d'accroître 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:

  • Pour satisfaire les parties prenantes. Pour de nombreux projets, il existe différents acteurs qui s'intéressent à la qualité du logiciel et qui ne sont pas impliqués dans le développement quotidien du logiciel (gestionnaires, responsables techniques, etc.). En disant "nous allons écrire tous les Les tests dont nous avons vraiment besoin "ne sont pas convaincants: ils doivent soit faire entièrement confiance, soit vérifier avec une surveillance constante (en supposant qu'ils aient la compréhension technique pour le faire). Fournir des normes mesurables et expliquer comment ils raisonnent raisonnablement les objectifs réels est meilleur.
  • Pour normaliser le comportement de l'équipe. Les intervenants mis à part, si vous travaillez sur une équipe où plusieurs personnes écrivent du code et des tests, il y a de la place pour l'ambiguïté pour ce qui est qualifié de «bien testé». Est-ce que tous vos collègues ont la même idée de quel niveau de test est suffisant? Probablement pas. Comment conciliez-vous cela? Trouvez une mesure sur laquelle vous pouvez tous vous entendre et acceptez-la comme une approximation raisonnable. Cela est particulièrement utile (mais pas exclusivement) dans les grandes équipes, où les prospects peuvent ne pas avoir un contrôle direct sur les développeurs débutants, par exemple. Les réseaux de confiance sont également importants, mais sans mesures objectives, il est facile pour un comportement de groupe de devenir incohérent, même si tout le monde agit de bonne foi.
  • Pour rester honnête. Même si vous êtes le seul développeur et seul acteur pour votre projet, vous pouvez avoir certaines qualités en tête pour le logiciel. Au lieu de faire des évaluations subjectives continues sur la qualité du logiciel (qui prend du travail), vous pouvez utiliser la couverture de code comme une approximation raisonnable, et laisser les machines la mesurer pour vous.

Quelles statistiques utiliser

La couverture de code n'est pas une mesure unique. Il existe plusieurs façons de mesurer la couverture. La norme dépend de ce que vous utilisez pour satisfaire cette norme.

J'utiliserai deux mesures communes comme exemples d'utilisation des normes:

  • Couverture de déclaration: Quel pourcentage de déclarations a été exécuté lors des tests? Utile pour avoir une idée de la couverture physique de votre code: Combien de code que j'ai écrit ai-je réellement testé?
    • Ce type de couverture prend en charge un argument de correction plus faible, mais est également plus facile à atteindre. Si vous n'utilisez que la couverture de code pour vous assurer cette les choses sont testées (et non pas comme un indicateur de la qualité des tests), la couverture des déclarations est probablement suffisante.
  • Couverture de branche: Quand il y a une logique de branchement (par exemple un if), les deux branches ont-elles été évaluées? Cela donne un meilleur sens du couverture logique de votre code: Combien de chemins possibles mon code peut-il avoir testé?
    • Ce type de couverture est un indicateur bien meilleur qu'un programme a été testé sur un ensemble complet d'intrants. Si vous utilisez la couverture de code comme votre meilleure approximation empirique pour la confiance en l'exactitude, vous devez définir des normes basées sur la couverture de branche ou similaire.

Il y a beaucoup d'autres métriques (la couverture des lignes est similaire à la couverture des déclarations, mais donne des résultats numériques différents pour les déclarations multilignes, par exemple, la couverture conditionnelle et la couverture des chemins sont similaires à la couverture des branches). l'exécution du programme que vous pourriez rencontrer.)

Quel pourcentage exiger

Enfin, revenons à la question initiale: Si vous définissez des normes de couverture de code, quel devrait être ce numéro?

Espérons qu'il est clair à ce stade que nous parlons d'une approximation pour commencer, de sorte que tout nombre que nous choisissons sera intrinsèquement approximatif.

Quelques chiffres que l'on pourrait choisir:

  • 100%. Vous pourriez choisir ceci parce que vous voulez être sûr que tout est testé. Cela ne vous donne aucune idée de la qualité du test, mais vous indique qu'un test de qualité a touché chaque énoncé (ou branche, etc.). Cela revient à un degré de confiance: si votre couverture est inférieure à 100% , toi connaître un sous-ensemble de votre code n'a pas été testé.
    • Certains pourraient argumenter que c'est stupide, et vous devriez seulement tester les parties de votre code qui sont vraiment importantes. Je dirais que vous devriez seulement maintenir les parties de votre code qui sont vraiment importantes. La couverture du code peut être améliorée en supprimant également le code non testé.
  • 99% (ou 95%, d'autres chiffres dans les années 90.) Approprié dans les cas où vous voulez transmettre un niveau de confiance similaire à 100%, mais laissez-vous une marge pour ne pas vous inquiéter du coin de code parfois difficile à tester.
  • 80%. J'ai déjà vu ce numéro plusieurs fois et je ne sais pas exactement d'où il provient. je pense il pourrait s'agir d'un détournement étrange de la règle 80-20; généralement, l'intention ici est de montrer que plus de votre code est testé. (Oui, 51% serait aussi "le plus", mais 80% est plus représentatif de ce que la plupart des gens signifier par la plupart.) Ceci est approprié pour les cas intermédiaires où «bien testé» n'est pas une priorité élevée (vous ne voulez pas gaspiller d'effort sur les tests de faible valeur), mais c'est une priorité suffisante aimer avoir une certaine norme en place.

Je n'ai pas vu de chiffres inférieurs à 80% en pratique, et j'ai du mal à imaginer un cas où l'on pourrait les définir. 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 l'objectif. La couverture de code est juste une information; cela peut être pertinent pour d'autres objectifs. Par exemple, si vous êtes préoccupé par la maintenabilité, vous vous intéressez probablement au couplage lâche, qui peut être démontré par la testabilité, qui peut à son tour être mesurée (de certaines façons) par la couverture de code. Ainsi, votre norme de couverture de code fournit également une base empirique pour l'approximation de la qualité de «maintenabilité».


28
2018-01-09 20:44



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 fini.

Le processus sous-jacent est le suivant:

  1. J'écris mes tests pour exercer toutes les fonctionnalités et les cas de bord que je peux penser (généralement en travaillant à partir de la documentation).
  2. Je lance les outils de couverture de code
  3. J'examine toutes les lignes ou les chemins non couverts et tout ce que je considère pas important ou inaccessible (en raison de la programmation défensive) je marque comme ne comptant pas
  4. J'écris de nouveaux tests pour couvrir les lignes manquantes et améliore la documentation si ces cas marginaux ne sont pas mentionnés.

Ainsi, si mes collaborateurs et moi-même ajoutons du nouveau code ou modifions les tests à l’avenir, il existe une ligne claire pour nous indiquer si nous avons manqué quelque chose d’important: la couverture est tombée en dessous de 100%. Cependant, il offre également la souplesse nécessaire pour gérer différentes priorités de test.


21
2017-10-07 15:58



J'aurais un autre anectode sur la couverture de test que j'aimerais partager.

Nous avons un énorme projet dans lequel, sur Twitter, j'ai noté que, avec 700 tests unitaires, nous avons seulement 20% de couverture de code.

Scott Hanselman a répondu avec paroles de sagesse:

Est-ce le droit 20%? Est-ce le 20%   cela représente le code de vos utilisateurs   frapper le plus? Vous pourriez ajouter 50 autres   tests et seulement ajouter 2%.

Encore une fois, il revient à mon Testivus on Code Coverage Répondre. Combien de riz devriez-vous mettre dans le pot? Ça dépend.


18
2017-09-18 04:42



85% serait un bon point de départ pour les critères d'enregistrement.

J'ai probablement choisi une variété de barres supérieures pour les critères d'expédition - en fonction de la criticité des sous-systèmes / composants testés.


7
2017-09-18 04:27



Si ce monde était parfait, 100% du code serait couvert par des tests unitaires. Cependant, puisque ce n'est pas un monde parfait, c'est une question de temps. Par conséquent, je vous recommande de vous concentrer moins sur un pourcentage spécifique et de vous concentrer davantage sur les domaines critiques. Si votre code est bien écrit (ou au moins un fac-similé raisonnable), 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, vous rencontrez un problème de code, de documentation ou de cas de test. Toutes sont bonnes à examiner.

Bonne chance!


7
2017-09-18 04:30



Pour un système bien conçu, où les tests unitaires ont conduit le développement depuis le début, je dirais 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:

  • Les lignes couvertes ne correspondent pas à la logique testée et il ne faut pas trop lire le pourcentage.

C'est vrai, mais il y a quelques points importants à faire sur la couverture du code. Dans 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 l'analyse de la couverture du code ajouter de la 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 de test (et spécifiquement 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 métrique de couverture du code, vous ne devez pas avoir un pourcentage fixe (arbitraire) à remplir. Cela ne vous donne pas les avantages réels de l'analyse de couverture de code à mon avis. Au lieu de cela, définissez les métriques suivantes:

  • Low Water Mark (LWM), le plus petit nombre de lignes découvertes jamais vues dans le système testé
  • High Water Mark (HWM), le pourcentage de couverture de code le plus élevé jamais enregistré pour le système testé

Un nouveau code ne peut être ajouté que si nous n'allons pas au-dessus du LWM et que nous n'allons pas en dessous du HWM. En d'autres termes, la couverture de code est pas autorisé à diminuer, et le nouveau code devrait ê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 vieilles poubelles bien testées 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 brisées, mais pour votre intégration au quotidien, mon expérience est que ces mesures sont très utiles. Ils donnent les deux implications suivantes.

  • Le code testable est promu. Lorsque vous ajoutez un 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 de test du code existant augmente avec le temps. Lorsque vous ajoutez un nouveau code et que vous ne pouvez pas le couvrir avec un scénario de test, vous pouvez essayer de couvrir un code hérité à la place pour contourner la règle LWM. Cette tricherie parfois nécessaire donne au moins l'effet secondaire positif que la couverture du code hérité augmentera au fil du temps, ce qui rend l'application apparemment rigoureuse de ces règles assez pragmatique dans la pratique.

Et encore une fois, si la boucle de rétroaction est trop longue, il peut être complètement inopportun de configurer quelque chose comme ça dans le processus d'intégration.

Je voudrais également mentionner deux avantages plus généraux de la métrique de couverture de code.

  • L'analyse de la couverture du code fait partie de l'analyse du code dynamique (par opposition à l'analyse statique, c'est-à-dire de la charpie). Problèmes rencontrés lors de l'analyse de code dynamique (par des outils tels que la famille purifier, http://www-03.ibm.com/software/products/en/rational-purify-family) sont des choses comme des lectures de mémoire non initialisées (UMR), des 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 le plus difficile à couvrir dans un scénario de test est généralement les cas anormaux dans le système, mais si vous voulez que le système échoue correctement (trace d'erreur au lieu de crash), vous pouvez essayer de couvrir les cas anormaux. dans l'analyse de code dynamique aussi bien. Avec juste un peu de malchance, une UMR peut conduire à une erreur de segmentation 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 de mise en œuvre. Comment cette fonction peut-elle être écrite de manière plus testable? Comment allez-vous essayer de couvrir ce cas anormal, etc.

Et un négatif, pour être complet.

  • Dans un grand projet avec de nombreux développeurs impliqués, tout le monde ne va pas être un test-génie à coup sûr. Certaines personnes ont tendance à utiliser la métrique de couverture de code comme preuve que le code est testé et ceci est très loin de la vérité, comme mentionné dans de nombreuses autres réponses à cette question. C'est une métrique unique qui peut vous apporter de bons avantages si elle est utilisée correctement, mais si elle est mal utilisée, elle peut en fait conduire à de mauvais tests. Outre les effets secondaires très importants mentionnés ci-dessus, une ligne couverte montre uniquement que le système testé peut atteindre cette ligne pour certaines données d'entrée et qu'il peut s'exécuter sans se bloquer ou se bloquer.

7
2017-07-25 07:45



Beaucoup de 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.

Dans le monde du .Net, les gens citent souvent 80% comme raisonnables. Mais ils disent cela au niveau de la solution. Je préfère mesurer au niveau du projet: 30% pourraient convenir pour un projet d'interface utilisateur si vous avez des tests de sélénium, etc. ou manuels, 20% pour le projet de couche de données pourrait être correct, mais 95% couche de règles, sinon totalement nécessaire. Ainsi, la couverture globale peut être, disons, de 60%, mais la logique commerciale critique peut être beaucoup plus élevée.

J'ai aussi entendu ceci: aspirer à 100% et vous atteindrez 80%; mais aspirez à 80% et vous atteindrez 40%.

Bottom line: Appliquez la règle 80:20 et laissez le nombre de bogues de votre application vous guider.


5
2017-07-29 23:50



J'utilise cobertura, et quel que soit le pourcentage, je vous recommande de garder les valeurs de la tâche cobertura-check à jour. Au minimum, continuez à augmenter le total et le total des ramifications juste en dessous de votre couverture actuelle, mais jamais abaisser ces valeurs. Reliez également la propriété d'échec de compilation Ant à cette tâche. Si la construction échoue en raison d'un manque de couverture, vous connaissez le code ajouté de quelqu'un, mais vous ne l'avez pas testé. Exemple:

<cobertura-check linerate="0"
                 branchrate="0"
                 totallinerate="70"
                 totalbranchrate="90"
                 failureproperty="build.failed" />

4
2018-04-27 23:29