Unité de test de code de la couverture - avez-vous une couverture de 100%?
Faire vos tests unitaires constituent 100% de couverture de code? Oui ou non, et pourquoi ou pourquoi pas.
- Ne peut pas dire que je n'ai jamais réservé un vol pour vraiment tester mon code.. 😛
- Vous devriez vérifier cette question: stackoverflow.com/questions/90002/...
Vous devez vous connecter pour publier un commentaire.
Pas pour plusieurs raisons :
et de l'unité de test:
Le test réussit, et votre code de couverture est de 100%. Toutefois, si vous ajoutez un autre test:
alors vous obtiendrez un
NullPointerException
. Et comme vous avez été à 100% avec le premier test, vous n'avez pas nécessairement écrire le second!Généralement, je considère que le critique code doit être couvert à près de 100%, tandis que l'autre code peut être couvert à 85-90%
À tous de la couverture de 90% testeur:
Le problème avec cela est que les 10% dur pour le code de test est aussi le non-trivial de code qui contient 90% de la bogue! C'est la conclusion que j'ai obtenu empiriquement après de nombreuses années de TDD.
Et après tout, c'est assez simple conclusion. Ce 10% est difficile de tester le code, il est difficile de test parce que - elle le reflet d'un travail délicat problème ou délicate, à défaut de conception ou les deux. Ces raisons exactes qui conduit souvent à code bogué.
Mais aussi:
Non, car il existe un compromis entre l'idéal de l'unité des tests et effectivement la finition d'un projet 🙂
Il est rarement pratique pour obtenir 100% de couverture de code dans un non-trivial système. La plupart des développeurs qui écrivent des tests unitaires tirer pour le mi-haute, 90.
Un outil de tests automatisés comme Pex peut aider à augmenter la couverture de code. Il fonctionne par la recherche de dur-à-trouver des cas limites.
Oui nous faisons.
Cela dépend de la langue et le cadre que vous utilisez comme facile, qui est de parvenir à bien.
Nous sommes à l'aide de Ruby on Rails pour mon projet actuel. Ruby est très "mockable" que vous pouvez stub/se moquer de grands morceaux de votre code, sans avoir à construire en trop compliqué de la classe de composition et de construction des conceptions que vous avez à faire dans d'autres langues.
Cela dit, nous n'avons que 100% ligne de couverture (en gros ce rcov vous donne). Vous avez encore de penser à tester toutes les branches.
Ce n'est possible que si vous l'inclure dès le départ comme une partie de votre version d'intégration continue, et briser la construction si la couverture est inférieur à 100%, incitant les développeurs à corriger immédiatement il. Vous pouvez bien sûr choisir un autre numéro de la cible, mais si vous êtes de départ frais, il n'y a pas beaucoup de différence pour les efforts visant à obtenir à partir de 90% à 100%
Nous avons aussi un tas d'autres paramètres qui cassent le construire si elles franchissent un seuil donné (de la complexité cyclomatique, la duplication par exemple) ces vont tous ensemble et les aider à se renforcer les unes les autres.
Encore une fois, vous avez vraiment à avoir ce genre de choses en place depuis le début de continuer à travailler à un niveau strict - c'est ça ou définir une cible, vous pouvez frapper, et peu à peu à cliquet jusqu'à vous arrivez à un niveau que vous êtes heureux avec.
Ne faisant cela, ajouter de la valeur? J'étais sceptique au début, mais je peux honnêtement dire que oui, il le fait. Pas principalement parce que vous avez testés code (même si c'est certainement un avantage), mais plus en termes d'écrire du code simple qui est facile à tester et à raison. Si vous savez que vous ont d'avoir 100% de couverture de test, vous arrêter d'écrire trop complexe if/else/tout/try/catch monstruosités et Keep It Simple Stupid.
Ce que je fais quand j'ai la chance est pour insérer des déclarations sur chaque branche du code qui peut être grepped et que l'enregistrement s'ils ont été touchés, de sorte que je peux faire une sorte de comparaison pour voir les déclarations n'ont pas été touchés. C'est un peu une corvée, donc je ne suis pas toujours bonne à ce sujet.
Je viens de construire une petite INTERFACE utilisateur de l'application à utiliser dans les ventes aux enchères caritatives, qui utilise MySQL comme base de données. Depuis que j'ai vraiment, vraiment ne voulais pas qu'il pause au milieu d'une vente aux enchères, j'ai essayé quelque chose de nouveau.
Depuis qu'il a été en VC6 (C++ + MFC), j'ai défini deux macros:
et puis j'ai saupoudré
dans tout le code, sur chaque chemin à part que j'ai pu trouver, et dans chaque routine.
Ensuite, j'ai couru le programme sous le débogueur, et à chaque fois il a frappé un
TCOV
, il s'arrête.Je regarde le code pour des problèmes évidents, et puis le modifier pour
_COV
, puis continuez. Le code à recompiler à la volée et de passer à la prochaineTCOV
.De cette façon, je me suis lentement, laborieusement, éliminé assez
TCOV
états sorte qu'il serait fonctionner "normalement".Après un certain temps, je grepped le code pour
TCOV
, et qui a montré ce code je n'avais pas testé. Ensuite, je suis retourné et il a couru de nouveau, assurez-vous de l'essai de plus de branches que je n'avais pas essayé plus tôt.J'ai continué à faire cela jusqu'à ce qu'il n'y avait pas
TCOV
déclarations de gauche dans le code.Cela a pris quelques heures, mais dans le processus, j'ai trouvé et corrigé plusieurs bugs. Il n'y a aucun moyen je pourrais avoir eu la discipline de faire et de suivre un plan de test qui aurait été approfondie.
Non seulement je sais que j'ai couvert toutes les branches, mais il m'avait fait regarder chaque branche alors qu'il était en cours d'exécution - un très bon type de revue de code.
Donc, si oui ou non vous utilisez un outil de couverture, c'est un bon moyen pour éradiquer les bugs qui pourraient autrement se cachent dans le code jusqu'à ce qu'un plus embarrassante temps.
Personnellement, je trouve 100% de couverture de test pour être problématique sur plusieurs niveaux. D'abord et avant tout, vous devez vous assurer que vous sont de plus tangible, de réduction des coûts des prestations de l'unité de tests que vous écrivez. En outre, les tests unitaires, comme tout autre code, sont CODE. Cela signifie que, à l'instar de tout autre code, doivent être vérifiés pour l'exactitude et maintenu. Que plus de temps de la vérification de code supplémentaire de la justesse et de l'entretenir et de garder ces tests valides en réponse à des changements de code de commerce, et augmente le coût. Atteindre 100% de couverture de test et de s'assurer que vous tester, vous êtes le code de manière aussi approfondie que possible est un louable effort, mais d'atteindre à tout prix...eh bien, est souvent trop coûteuse.
Il y a beaucoup de moments où couvrant d'erreur et de contrôle de la validité qui sont en place pour couvrir frange ou extrêmement rare, mais possible, les cas exceptionnels sont un exemple de code qui n'a pas nécessairement besoin d'être couvert. Le montant de temps, effort (et en fin de compte de l'argent) qui doit être investi pour atteindre un niveau de couverture de ces rares frange est souvent gaspillage à la lumière des autres besoins de l'entreprise. Les propriétés sont souvent une partie de code, surtout avec C# 3.0, n'a pas besoin d'être testés comme la plupart, si pas tous, les propriétés se comportent exactement de la même façon, et sont excessivement simples (une seule instruction de retour ou de l'ensemble.) Investir d'énormes quantités de temps d'habillage des tests unitaires autour de milliers de propriétés pourraient très probablement être mieux investi ailleurs, un plus grand, plus de valeur tangible en terme de retour sur investissement peut être réalisé.
Au-delà de la simple réalisation de 100% de couverture de test, il y a des problèmes similaires avec la tentative de définition de la "perfection" de l'unité. Se moquant des cadres ont progressé à un degré étonnant de nos jours, presque tout peut se moque (si vous êtes prêt à payer de l'argent, TypeMock peut réellement se moquer de tout et de rien, mais il coûte beaucoup.) Cependant, il arrive souvent que les dépendances de votre code n'ont pas été écrits dans un simulacre de la mesure moyen (c'est en fait un problème majeur de la grande masse de la .NET framework lui-même.) Investir du temps pour atteindre le champ d'application d'un test est utile, mais en les plaçant dans des quantités excessives de temps à se moquer de tout et de rien sous le visage du soleil, de l'ajout de couches d'abstraction et d'interfaces pour le rendre possible, est de nouveau le plus souvent un gaspillage de temps, d'effort et de l'argent.
Le but ultime avec des tests ne devrait pas vraiment être d'atteindre le summum de la couverture de code. Le but ultime devrait être la réalisation de la plus grande valeur par unité de temps investi dans l'écriture de tests unitaires, tout en couvrant autant que possible en ce moment. La meilleure façon d'y parvenir est de prendre l'approche BDD: Indiquez vos préoccupations, de définir le contexte, et de vérifier les résultats attendus se produire pour n'importe quel morceau de comportement en cours de développement (comportement...pas d'unité.)
Pas parce que j'ai passé mon temps à ajouter de nouvelles fonctionnalités qui aident les utilisateurs plutôt que difficile à écrire obscur tests qui offrent peu de valeur. Je dis unité de test les grandes choses, les belles choses et des choses qui sont fragiles.
Sur un nouveau projet, je pratique du TDD et conserver 100% de la couverture en ligne. Il se produit principalement naturellement par la DRT. Des lacunes dans la couverture sont généralement en valeur l'attention et sont facilement remplies. Si l'outil de couverture je suis aide fournie direction de couverture ou quelque chose d'autre, je ferais attention à ce que, bien que je n'ai jamais vu branche de la couverture me dire quelque chose, probablement parce que l'ATS a obtenu en premier.
Mon principal argument en faveur du maintien de la couverture de 100% (si vous vous souciez de la couverture à tous), c'est que il est beaucoup plus facile de maintenir une couverture de 100% à gérer à moins de 100% de couverture. Si vous avez une couverture de 100% et il tombe, vous savez tout de suite pourquoi et peut facilement réparer, parce que la chute est dans le code que vous venez de travailler. Mais si vous vous arrêtez à 95% ou que ce soit, il est facile de rater la couverture des régressions et vous êtes toujours re-examiner connu des lacunes. C'est la raison exacte pour laquelle les meilleures pratiques actuelles requiert l'un de la suite de test à passer complètement. Rien de moins est plus difficile, non pas plus facile à gérer.
Mon attitude est certainement renforcé par le fait d'avoir travaillé dans le Rubis pour un certain temps, où il y a d'excellentes infrastructures de test et d'essai, les chambres doubles sont faciles. 100% de couverture est également facile en Python. Je pourrais avoir à baisser mes normes dans un environnement avec des prête moins d'outils.
J'aimerais avoir les mêmes normes sur les anciens projets, mais je n'ai jamais trouvé pratique pour emporter une grande application avec la médiocre couverture jusqu'à 100% de couverture; j'ai eu à régler pour 95% à 99%. Il a toujours été juste trop de travail pour revenir en arrière et de couvrir l'ensemble de l'ancien code. Cela ne contredit pas mon argument selon lequel il est facile de garder une base de code à 100%; il est beaucoup plus facile lorsque vous maintenez que la norme depuis le début.
J'en général d'écrire des tests unitaires comme une régression de prévention de la méthode. Lorsqu'un bug est signalé que j'ai à corriger, j'ai créer une unité de test pour s'assurer qu'il n'a pas de refaire surface dans l'avenir. Je peut créer un peu de tests pour les sections de fonctionnalité, je dois veiller à rester intact (ou complexes inter-partie d'interactions), mais j'ai l'habitude de vouloir pour la correction de bug pour me dire un seul est nécessaire.
J'ai l'habitude de gérer de frapper 93..100% avec ma couverture, mais je ne suis pas objectif à 100% plus. J'ai l'habitude de le faire et tout c'est faisable, ça ne vaut pas l'effort au-delà d'un certain point car les essais aveuglément évident n'est généralement pas nécessaire. Bon exemple de cela pourrait être le véritable évaluation de la direction de code suivant ciselée
Cependant ce qui est important à atteindre est de près de 100% de couverture sur fonctionnelle parties de la classe que possible, car ce sont les eaux dangereuses de votre application, la brume de la tourbière de ramper de bugs et de comportements indéfinis et bien sûr de l'argent de décisions de cirque de puces.
De Ted Neward blog.
Je n'ai que 100% de couverture sur les nouveaux morceaux de code qui ont été écrits avec testabilité à l'esprit. Avec une bonne encapsulation, chaque classe et la fonction peut avoir fonctionnelle tests unitaires qui, simultanément, de donner à près de 100% de couverture. C'est alors qu'une question de l'ajout de certains examens complémentaires qui couvrent certains cas limites pour vous à 100%.
Vous ne devriez pas écrire des tests juste pour obtenir une couverture. Vous devriez écrire des tests fonctionnels que le test de l'exactitude ou de la conformité. Par une bonne spécification fonctionnelle qui couvre tous les motifs et une bonne conception de logiciel, vous pouvez obtenir une bonne couverture pour gratuit.
Oui, j'ai eu des projets qui ont eu 100% de couverture en ligne. Voir ma réponse à un semblable question.
Vous peut obtenir 100% de ligne couverture, mais comme d'autres l'ont fait ici, sur DONC et ailleurs sur internet sa peut-être seulement un minimum. Lorsque vous envisagez de chemin et de la direction générale de la couverture, il y a beaucoup plus de travail à faire.
L'autre façon de voir les choses, c'est pour essayer de rendre votre code si simple que son facile à obtenir 100% de couverture de ligne.
Dans de nombreux cas, ce n'est pas la peine d'obtenir 100% l'état de la couverture, mais dans certains cas, il est la peine. Dans certains cas 100% l'état de la couverture est bien trop lax une exigence.
La principale question à se poser est: "quel est l'impact si le logiciel ne parvient pas (produit le mauvais résultat)?". Dans la plupart des cas, l'impact d'un bug est relativement faible. Par exemple, vous avez peut-être d'aller corriger le code dans un délai de quelques jours, puis exécutez de nouveau quelque chose. Toutefois, si l'impact est "quelqu'un pourrait mourir dans les 120 secondes", alors que c'est un impact énorme, et vous devriez avoir un beaucoup plus d'essai de couverture de juste 100% l'état de la couverture.
Je mène la Core Infrastructure Initiative Des Meilleures Pratiques De L'Insigne pour la Linux Foundation. Nous ne 100% l'état de la couverture, mais je ne dirais pas que c'est strictement nécessaire. Pendant longtemps, nous étions très proches de 100%, et simplement décidé de faire le dernier petit pour cent. Nous ne pouvions pas vraiment justifier la dernière quelques pour cent sur l'ingénierie des raisons, cependant; ces derniers pour cent ont été ajoutés uniquement comme "la fierté de la main d'œuvre". Je fais un très petit morceau de l'esprit d'avoir une couverture de 100%, mais en réalité il n'était pas nécessaire. Nous étions plus de 90% l'état de la couverture seulement à partir des tests normaux, et c'était bon pour nos fins. Cela dit, nous voulons le logiciel afin d'être solide comme le roc, et avoir 100% l'état de la couverture nous a aidé à y arriver. Il est également plus facile d'obtenir 100% l'état de la couverture aujourd'hui.
Il est toujours utile de mesurer la couverture, même si vous n'avez pas besoin de 100%. Si vos tests n'ont pas de couverture convenable, vous devrait être concernés. Une mauvaise suite de tests pour avoir une bonne instruction de la couverture, mais si vous n'avez pas la bonne instruction de la couverture, alors, par définition, vous avez une mauvaise suite de tests. Combien vous avez besoin est un compromis: quels sont les risques (probabilité et de l'impact) à partir du logiciel qui est totalement non testés? Par définition, il est plus susceptible d'avoir des erreurs (vous n'avez pas le tester!), mais si vous et vos utilisateurs peuvent vivre avec ces risques (probabilité et de l'impact), c'est correct. Pour beaucoup de bas-impact des projets, je pense que 80%-90% l'état de la couverture est bien, avec du mieux-être mieux.
D'autre part, si les gens risquent de mourir de erreurs dans votre logiciel, puis à 100% l'état de la couverture n'est pas assez. J'aurais au moins ajouter la branche de la couverture, et peut-être plus, pour vérifier la qualité de vos tests. Les normes comme DO-178C (pour les systèmes embarqués) de prendre cette approche - si une défaillance est mineur, pas une grosse affaire, mais si une défaillance pourrait avoir des conséquences catastrophiques, alors beaucoup plus de tests rigoureux est nécessaire. Par exemple, DO-178C nécessite MC/DC couverture pour la plupart des logiciels critiques (le logiciel qui peut rapidement tuer des gens si il fait une erreur). MC/DC, c'est bien plus ardu que l'énoncé de la couverture ou de la même branche de la couverture.
Il y a beaucoup de bonnes informations ici, je voulais juste ajouter un peu plus d'avantages que j'ai trouvé lors de viser 100% de couverture de code dans le passé
Car il est plus facile d'enlever une ligne que d'écrire un scénario de test, en visant une couverture de 100% vous oblige à justifier chaque ligne, chaque branche, chaque instruction si, menant souvent à la découverte d'un moyen beaucoup plus simple de faire des choses qui demandent moins de tests
Vous pouvez obtenir une haute couverture de test par écrit beaucoup de petits tests de tests de minuscules bouts de mise en œuvre, comme vous allez. Cela peut être utile pour les passages techniques de la logique, mais le faire pour chaque morceau de code n'importe comment trivial peut être fastidieux, vous ralentir et devenir un vrai fardeau de l'entretien également rendre votre code plus difficile à refactoriser. D'autre part, il est très difficile de parvenir à une bonne couverture de test à très haut niveau à la fin des tests de comportement, parce que en général, la seule chose que vous test comporte de nombreux composants qui interagissent de façon compliquée et les permutations de cas possibles devenir très volumineux très rapidement. Donc si vous êtes à la pratique et qui souhaitent également pour objectif de 100% de couverture de test, vous apprendrez rapidement à trouver un niveau de granularité pour vos tests où vous pouvez atteindre un niveau élevé de couverture avec quelques bons tests. Vous pouvez atteindre cet objectif par l'essai de composants à un niveau où ils sont assez simples que vous pouvez raisonnablement couvrir tous les cas de bord, mais aussi assez compliqué, que vous pouvez tester significative de comportement. Ces tests finissent par être simple, concret et utile pour l'identification et la correction des bogues. Je pense que c'est une bonne compétence et améliore la qualité du code et de la maintenabilité.
Il y a un moment j'ai fait une petite analyse de la couverture du JUnit mise en œuvre, le code écrit et testé par, entre autres, Kent Beck et David Saff.
De l'conclusions: