2010-03-18 17 views
5

Sono un po 'nuovo nel modulo Devel :: Cover, ma l'ho trovato molto utile per assicurarmi di non mancare i test.Come posso ottenere una copertura di prova del 100% in un modulo Perl che utilizza DBI?

Un problema che sto incontrando è la comprensione del rapporto di Devel :: Cover. Ho esaminato la documentazione, ma non riesco a capire cosa devo testare per ottenere una copertura del 100%.

Edit - dovrei chiarire che non sto dicendo che ho bisogno una copertura del 100%, perché, come più persone sottolineano, copertura del 100% è un termine sciolto, non non significa che il mio codice è privo di bug, e potrebbe non essere sempre completamente necessario. Dato che io sono un principiante Devel :: Copertina, Sono interessato a conoscere perché il mio codice non è una copertura del 100%, nel caso in cui mi manca alcuni importanti test.

Ecco l'output del rapporto di copertura:

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") 

e qui è e l'esempio del mio codice che verifica questa linea specifica:

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)'); 

Questo test passa - il collegamento fa lancia un errore e realizza il mio test "throws_ok".

Ho alcuni test per una connessione riuscita, motivo per cui penso di avere una copertura del 33%, ma se lo sto leggendo correttamente, cover pensa che non sto testando la parte "|| croak" di la dichiarazione. Pensavo di essere, con il test "throws_ok", ma ovviamente mi manca qualcosa.

Qualcuno ha consigli su come posso testare il mio DBI-> connettere la linea con successo?

Grazie!

Edit:

Brian mi soffiata al report HTML e la tabella di verità che spiega il motivo per cui la linea # 41 non passa. L'unico problema è che non riesco a capire cosa mi sta dicendo. Immagino che il vero fulcro della mia domanda sia perché questa linea specifica non supera la copertura.

Ecco la tabella di verità:

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) 

Se qualcuno potrebbe aiutare a spiegare questo tabella di verità, lo apprezzerei. E 'stato anche detto che per passare la copertura ho bisogno di avere un oggetto di database fittizio, ma non vedo proprio come nulla nei risultati di copertura che mi indicherebbe in questo.

Grazie ancora!

+1

Cercare di ottenere una copertura completa è probabilmente uno sforzo inutile. La copertura della filiale dovrebbe essere più che sufficiente. Se il tuo codice è così importante da richiedere la copertura delle condizioni, non dovresti scriverlo in Perl. Come vantaggio collaterale, Devel :: Cover funziona molto più velocemente quando non si raccolgono dati sulla copertura delle condizioni. –

+0

"Copertura del 100%" non ha ancora senso se non si qualifica come si sta facendo copertura. Copertura di linea? Copertura della filiale? Copertura del percorso? Ognuno ha diversi livelli di confidenza e difficoltà di implementazione. Anche allora, stai valutando il recupero dell'investimento per il tempo investito. È un sistema di sicurezza che potrebbe uccidere qualcuno? In tal caso, la copertura del 100% del percorso non sarà sufficiente: avrete bisogno di test di sistema approfonditi e anche di ingegneri esperti. Coinvolge sistemi finanziari? In tal caso, dovresti fare anche un controllo di sicurezza. qualsiasi copertura% non equivale a "finito". –

+0

@Robert P - Non sto cercando di ottenere una copertura del 100% - Sto cercando di capire se mi manca un test sul mio DBI-> connect. Dato che sono nuovo di Devel :: Cover, penso che sia bene sapere perché il mio codice non è coperto al 100%. Ho letto entrambi i blog collegati da bdfoy e so che non ho bisogno di una copertura al 100%. Proprio come Perl :: Critico - passare critici senza alcun preavviso non è abbastanza. – BrianH

risposta

9

Inoltre, non esagerare con il 100% di copertura del test. L'obiettivo è testare completamente la tua applicazione, non ottenere punteggi perfetti in Devel :: Cover. Vedere i messaggi di Ovidio sul tema:

Nel tuo caso, sembra che non si coprono tutti i rami, in modo da non si ottiene un punteggio perfetto. È necessario test che esercitano entrambi i lati di quello ||. Otterrai una copertura del 33% in percentuale perché gestisci solo un terzo dei casi per quella linea. Il report HTML di Devel :: Cover ti mostra la tabella di verità e quali casi ti mancano.

La tabella di verità mostra gli stati possibili che è necessario coprire per la ramificazione. A 1 mostra una condizione vera, 0 mostra una condizione falsa e X mostra una condizione che non verrà raggiunta. Devi testare tutte le combinazioni che possono essere eseguite. Dal momento che il || è un operatore di corto circuito, non c'è bisogno di testare le condizioni di una volta uno di loro passa:

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 

Questo è un po 'estraneo al vostro problema particolare, ma trovo arriva spesso in questi i problemi. Anche se lo Effective Perl Programming è un mese così lontano dagli scaffali, Josh McAdams ha passato parecchio tempo a parlare di un'iniezione di dipendenza in Perl. Se hai difficoltà a testare il tuo codice, di solito hai un problema di progettazione. Se stai generando internamente oggetti di database in subroutine, ad esempio, ti stai dipingendo in un angolo. Ecco perché potrebbe essere difficile da testare. Questo potrebbe non essere il problema nel tuo caso, ma è qualcosa su cui riflettere.

+0

Penso che il punto principale di Ovid fosse che il 100% di copertura del test non è sinonimo di "no bug", al contrario del rifiuto dell'idea di copertura al 100%. "Se non è coperto, è rotto. Every. Single. Time." – DVK

+0

Questo era esattamente il punto di Ovid. Ecco perché ho detto fondamentalmente la stessa cosa nella mia seconda frase. –

+0

Sì, quei 2 post del blog sono in realtà ciò che mi ha spinto a guardare Devel :: Cover. Non sto davvero cercando di ottenere una copertura di prova del 100% - ero più curioso di sapere se mi mancava un test in questa specifica istanza che dovrei provare. E buoni consigli per avere un codice di prova difficile. In questo caso era un test che era già stato scritto. Volevo vedere quanto bene ho passato a Devel :: Cover, e sono rimasto perplesso sul DBI-> connect. Grazie per il consiglio! – BrianH

5

È necessario prendere in giro la libreria DBI (o qualsiasi altra dipendenza esterna) per coprire completamente i test dell'unità.

È possibile utilizzare Test :: MockObject, o qualsiasi altro approccio di derisione (ad esempio, la nostra azienda ha sviluppato la nostra libreria di mocking Perl molto potente).

Vedere anche this article in particolare su DBI beffardo.

Inoltre, assicurarsi di utilizzare l'ultima versione di Devel :: Cover. Una volta ho passato 3 giorni a lottare con un test unitario fino a quando mi resi conto che il bug non era nel mio codice, e non nel mio test di unità, ma nella versione precedente di Devel :: Cover che la mia azienda aveva installato. Ha letteralmente ignorato alcuni percorsi di codice nei casi "A || B".

+0

DBD :: Mock è abbastanza utile per questo. http://search.cpan.org/perldoc?DBD::Mock – daotoad

+0

LOL good timing daotoad - Ho appena aggiornato con un link che menziona DBD :: Mock 1 secondo fa :) – DVK

+0

Quindi la copertina è specificatamente in cerca di me per prendere in giro il mio database e stabilire una connessione fittizia, anche se sono riuscito a connettermi e ad interrompere con esito positivo? Sono un po 'familiare con Test :: MockObject, ma non sapevo su DBD :: Mock. Dovrò esaminarli ulteriormente. – BrianH

Problemi correlati