2010-03-18 5 views
5

Je suis un peu nouveau dans le module Devel :: Cover, mais je l'ai trouvé très utile pour m'assurer que je ne manque pas de tests.Comment puis-je obtenir une couverture de test de 100% dans un module Perl utilisant DBI?

Un problème que je rencontre est de comprendre le rapport de Devel :: Cover. J'ai regardé la documentation, mais je n'arrive pas à comprendre ce que j'ai besoin de tester pour obtenir une couverture à 100%.

Modifier - Je dois préciser que je ne dis pas que j'ai besoin une couverture de 100%, parce que plusieurs personnes signalent, une couverture de 100% est un terme lâche, ne veut pas dire que mon code est sans bug, et ne peut pas toujours être complètement nécessaire. Depuis que je suis nouveau à Devel :: Cover, je suis intéressé de savoir pourquoi mon code n'est pas une couverture de 100%, dans le cas où je manque quelques importants tests.

Voici la sortie du rapport de couverture:

line err stmt bran cond sub pod time code 
... 
36             sub connect_database { 
37    3     3  1 1126  my $self = shift; 
38    3 100       24  if (!$self->{dsn}) { 
39    1         7   croak 'dsn not supplied - cannot connect'; 
40              } 
41 ***  2   33     21  $self->{dbh} = DBI->connect($self->{dsn}, q{}, q{}) 
42               || croak "$DBI::errstr"; 
43    1         11  return $self; 
44             } 
... 
line err  %  l !l&&r !l&&!r expr 
----- --- ------ ------ ------ ------ ---- 
41 ***  33  1  0  0 'DBI'->connect($$self{'dsn'}, '', '') || croak("$DBI::errstr") 

Et voici et exemple de mon code qui teste cette ligne spécifique:

my $database = MyModule::Database->new({ dsn => 'Invalid DSN' }); 
throws_ok(sub { $database->connect_database() }, 
    qr/Can't connect to data source/, 
    'Test connection exception (invalid dsn)'); 

Ce test passe - la connexion ne lancer une erreur et remplit mon test "throws_ok". J'ai des tests qui testent une connexion réussie, c'est pourquoi je pense avoir une couverture de 33%, mais si je la lis correctement, je pense que je ne suis pas en train de tester la partie "|| croak" de la déclaration. Je pensais que j'étais, avec le test "throws_ok", mais évidemment, il me manque quelque chose.

Est-ce que quelqu'un a des conseils sur comment tester ma ligne DBI-> connect avec succès?

Merci!

Edit:

brian me averti le rapport HTML et la table de vérité qui explique pourquoi la ligne n ° 41 ne passe pas. Le seul problème est que je ne peux pas comprendre ce qu'il me dit. Je suppose que le vrai cœur de ma question est de savoir pourquoi cette ligne spécifique ne couvre pas la couverture.

Voici la table de vérité:

LINE # % # coverage # condition 
41 # 33 # A | B | deC# 'DBI'->connect($$self{'dsn'}, '', '') || croak("$DBI::errstr") 
    # # 0 | 0 | 0 # 
    # # 0 | 1 | 1 # 
    # # 1 | X | 1 # (THIS LINE IS Green - the rest are red) 

Si quelqu'un pourrait aider à expliquer cette table de vérité, je vous en serais reconnaissant. Il a également été mentionné que pour passer la couverture, j'ai besoin d'un faux objet de base de données, mais je ne vois pas très bien comment les résultats de la couverture pourraient m'indiquer.

Merci encore!

+1

Tenter d'obtenir une couverture complète est probablement un effort inutile. La couverture de la branche devrait être plus que suffisante. Si votre code est si important que vous avez besoin d'une couverture de conditions, vous ne devriez pas l'écrire en Perl. En tant que bénéfice secondaire, Devel :: Cover fonctionne beaucoup plus rapidement lorsque vous ne collectez pas de données de couverture de condition. –

+0

"100% de couverture" est toujours sans signification si vous ne qualifiez pas comment vous faites la couverture. Couverture de ligne Couverture de branche? Couverture de chemin Chacun a différents niveaux de confiance et de difficulté de mise en œuvre. Même alors, vous cherchez à récupérer le temps investi. Est-ce un système de sécurité critique qui pourrait tuer quelqu'un? Dans ce cas, une couverture de 100% ne suffira même pas: vous aurez besoin de tests approfondis du système ainsi que d'ingénieurs de test qualifiés. Cela implique-t-il des systèmes financiers? Dans ce cas, vous devriez également faire une vérification de sécurité. toute couverture% ne correspond pas à "fini". –

+0

@Robert P - Je ne cherche pas une couverture à 100% - J'essaie de comprendre si un test sur mon DBI-> connect me manque. Depuis que je suis nouveau à Devel :: Cover, je pense qu'il est bon de savoir pourquoi mon code n'est pas couvert à 100%. J'ai lu les deux blogs bdfoy ci-dessous, et je sais que je n'ai pas besoin d'une couverture de 100%. Tout comme Perl :: Critic - passer le critique sans aucun avertissement ne suffit pas. – BrianH

Répondre

9

Aussi, ne soyez pas trop accroché sur 100% de couverture de test. Le but est de tester pleinement votre application, et non d'obtenir des scores parfaits dans Devel :: Cover. Voir tous les messages d'Ovide sur le sujet:

Dans votre cas, il semble que vous ne couvre pas toutes les branches, afin de ne pas les scores parfaits. Vous avez besoin de tests qui exercent les deux côtés de ce ||. Vous obtenez une couverture de 33% car vous ne gérez qu'un tiers des cas pour cette ligne. Le rapport HTML de Devel :: Cover vous montre la table de vérité et les cas qui vous manquent.

Le tableau de vérité vous montre les états possibles que vous devez couvrir pour le branchement. Un 1 vous montre une condition qui est vraie, 0 vous montre une condition qui est fausse, et X vous montre une condition que vous n'atteindrez pas. Vous devez tester toutes les combinaisons pouvant être exécutées. Étant donné que le || est un opérateur de court-circuit, vous ne devez pas tester les conditions une fois l'un d'entre eux passe:

0 || 1  connect to database fails and croak succeeds 
0 || 0  connect to database fails and croak fails (unlikely) 
1 || X  connect to database succeeds, so short circuit 

C'est un peu sans rapport avec votre problème particulier, mais je trouve cela arrive souvent dans ces problèmes. Bien que Effective Perl Programming est un mois de si loin de frapper les étagères, Josh McAdams a passé beaucoup de temps à parler de l'injection de dépendance dans Perl. Si vous éprouvez des difficultés à tester votre code, vous avez généralement un problème de conception. Si vous générez en interne des objets de base de données dans des sous-programmes, par exemple, vous vous peignez dans un coin. C'est pourquoi il pourrait être difficile à tester. Ce n'est peut-être pas le problème dans votre cas, mais c'est quelque chose à penser.

+0

Je pense que le point principal d'Ovid était que 100% de couverture de test n'est pas synonyme de «pas de bugs», par opposition à rejeter l'idée de couverture à 100%. "Si ce n'est pas couvert, c'est cassé, chaque fois, seul." – DVK

+0

En effet c'était le point d'Ovide. C'est pourquoi j'ai dit à peu près la même chose dans ma deuxième phrase. –

+0

Yep - Ces 2 billets de blog sont en fait ce qui m'a fait regarder Devel :: Cover. Je n'essaie pas vraiment d'obtenir une couverture de test de 100% - j'étais plus curieux de savoir s'il me manquait un test dans ce cas précis que je devrais tester. Et un bon conseil pour avoir du mal à tester le code. Dans ce cas, c'était un test qui était déjà écrit. Je voulais voir à quel point j'ai dépassé Devel :: Cover, et je me suis retrouvé coincé sur DBI-> connect. Merci pour le conseil! – BrianH

5

Vous devez vous moquer de la bibliothèque DBI (ou de toute autre dépendance externe) afin de couvrir entièrement vos tests unitaires.

Vous pouvez utiliser Test :: MockObject ou toute autre approche de simulation (par exemple, notre société a développé notre propre bibliothèque de perlations Perl très puissante).

Voir également this article spécifiquement sur DBI moqueur.

Veuillez également vous assurer que vous utilisez la dernière version de Devel :: Cover. J'ai passé 3 jours à lutter avec un test unitaire jusqu'à ce qu'il m'est apparu que le bug n'était pas dans mon code, et pas dans mon test d'unité, mais dans l'ancienne version de Devel :: Cover que mon entreprise avait installée. Il a littéralement ignoré certains chemins de code dans les cas "A || B".

+0

DBD :: Mock est très pratique pour ça. http://search.cpan.org/perldoc?DBD::Mock – daotoad

+0

LOL bon timing daotoad - Je viens de mettre à jour avec un lien mentionnant DBD :: Mock il y a 1 seconde :) – DVK

+0

Donc, la couverture est spécifiquement à la recherche de ma base de données , et établir une connexion fictive, même si j'ai réussi à vous connecter et avorté avec succès? Je suis un peu familier avec Test :: MockObject, mais je ne connaissais pas DBD :: Mock. Je vais devoir regarder plus loin. – BrianH

Questions connexes