2009-08-30 10 views
12

Quando si esegue una suite di test delle applicazioni, desidero promuovere tutti gli avvisi di compilazione e di runtime Perl (ad esempio l'avviso "Variabile non inizializzata") in errori fatali in modo che io e gli altri sviluppatori indaghino e risolviamo il codice che genera l'avviso. Ma voglio solo farlo durante lo sviluppo e test CI. Nella produzione, gli avvertimenti dovrebbero rimanere come avvertimenti.Come dovrei promuovere gli avvisi Perl a errori fatali durante lo sviluppo?

ho provato quanto segue: In "t/lib" Ho creato un TestHelper.pm modulo:

# TestHelper.pm 
use warnings FATAL => qw(all); 
1; 

poi chiamato la suite di test in questo modo:

$ PERL5LIB=$PERL5LIB:./t/lib PERL5OPT=-MTestHelper.pm prove -l t/*.t 

Ma questo non ha avuto l'effetto desiderato di promuovere tutti gli avvertimenti in caso di errori fatali. Ho ricevuto gli avvertimenti normalmente ma gli avvertimenti non sembrano essere considerati fatali. Nota che tutti i miei script test.t hanno la riga "usa avvertimenti"; in loro - forse questo supera quello in TestHelper.pm perché "usa avvertimenti" ha un ambito locale?

Invece ho fatto questo:

# TestHelper.pm 
# Promote all warnings to fatal 
$SIG{__WARN__} = sub { die @_; }; 
1; 

Questo funziona, ma ha un odore di codice su di esso. Inoltre, non mi piace che si bombarda al primo avvertimento. Preferirei che la suite di test fosse completamente funzionante, registrando tutti gli avvertimenti, ma che lo stato del test alla fine fallì perché il codice funzionava con avvertimenti.

Esiste un modo migliore per ottenere questo risultato finale?

risposta

21

Penso che stiate cercando Test::NoWarnings.

+0

Quel modulo è esattamente quello di cui ho bisogno, grazie. Sai che funziona più o meno lo stesso che Friedo suggerisce sopra. :-) – Hissohathair

+0

Sfortunatamente Test :: NoWarnings non funziona ancora correttamente con "done_testing()", vedere https://rt.cpan.org/Public/Bug/Display.html?id=66485 e https: // rt. cpan.org/Ticket/Display.html?id=52412 –

17

Il motivo use warnings FATAL => qw(all); non funziona per voi perché use warnings è in ambito lessicale. Quindi qualsiasi avvertimento prodotto all'interno di TestHelper.pm sarebbe fatale, ma gli avvertimenti prodotti altrove funzioneranno normalmente.

Se si desidera attivare gli avvisi irreversibili a livello globale, penso che un gestore $SIG{__WARN__} sia probabilmente l'unico modo per farlo. Se non vuoi che esploda al primo avviso, puoi lasciare che il gestore li memorizzi in un array, quindi controllarlo in un blocco END.

my @WARNINGS; 
$SIG{__WARN__} = sub { push @WARNINGS, shift }; 

END { 
    if (@WARNINGS) {  
     print STDERR "There were warnings!\n"; 
     print "$_\n" for @WARNINGS; 
     exit 1; 
    } 
} 
+0

Capisco che "use warnings" sia in ambito lessicale. Ma il mio TestHelper.pm non ha avuto una dichiarazione "pacchetto". È implicito uno quando passo "-MTestHelper" tramite PERL5OPTS? – Hissohathair

+3

Lo scope lessicale non ha nulla a che fare con i pacchetti. Funziona dal punto di dichiarazione fino alla fine del file (o alla parentesi graffa finale, se si trovava all'interno di parentesi graffe). Non influenza mai il codice in un altro file. – cjm

+0

Ah. Eccellente grazie. – Hissohathair

Problemi correlati