2009-08-30 9 views
12

Podczas uruchamiania pakietu testów aplikacji chcę promować wszystkie ostrzeżenia dotyczące kompilacji i czasu pracy w Perlu (np. Ostrzeżenie "Niezainicjowana zmienna") w przypadku błędów krytycznych, aby umożliwić I i innym programistom zbadanie i naprawienie kodu generującego ostrzeżenie. Ale chcę to zrobić tylko podczas programowania i testowania CI. W produkcji ostrzeżenia powinny pozostać ostrzeżeniami.W jaki sposób powinienem promować ostrzeżenia Perla do błędów krytycznych podczas programowania?

Próbowałem następujących czynności: W "t/lib" I stworzył TestHelper.pm modułu:

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

wówczas nazywano zestaw testów takiego:

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

Ale to nie miało pożądany efekt promowania wszystkich ostrzeżeń na błędy krytyczne. Dostałem ostrzeżenia jako normalne, ale ostrzeżenia nie wydają się być traktowane jako śmiertelne. Zauważ, że wszystkie moje skrypty test.t mają wiersz "użyj ostrzeżeń"; w nich - może to przesadza z tym w TestHelper.pm, ponieważ "ostrzeżenia o korzystaniu" mają zasięg lokalny?

Zamiast Robiłem to:

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

To działa, ale ma zapachy kodu temat. Nie podoba mi się też, że bombarduje pierwsze ostrzeżenie. Wolałbym, aby pakiet testowy działał w pełni, rejestrując wszystkie ostrzeżenia, ale ostatecznie status testu się nie powiódł, ponieważ kod był uruchamiany z ostrzeżeniami.

Czy istnieje lepszy sposób na osiągnięcie tego wyniku końcowego?

Odpowiedz

21

Myślę, że szukasz Test::NoWarnings.

+0

Ten moduł jest dokładnie tym, czego potrzebuję, dzięki. Wiesz, że działa mniej więcej tak samo, jak sugeruje to friedo. :-) – Hissohathair

+0

Niestety Test :: NoWarnings jeszcze nie działa poprawnie z "done_testing()", zobacz https://rt.cpan.org/Public/Bug/Display.html?id=66485 i https: // rt. cpan.org/Ticket/Display.html?id=52412 –

17

Powód, dla którego use warnings FATAL => qw(all); nie działa, ponieważ use warnings ma zasięg leksykalny. Więc wszelkie ostrzeżenia wyprodukowane w TestHelper.pm będą śmiertelne, ale ostrzeżenia wyprodukowane w innym miejscu będą działać normalnie.

Jeśli chcesz włączyć globalne ostrzeżenia o zagrożeniach, myślę, że obsługa $SIG{__WARN__} jest prawdopodobnie jedynym sposobem na zrobienie tego. Jeśli nie chcesz, aby wysadzono w powietrze przy pierwszym ostrzeżeniu, możesz pozwolić swojemu handlerowi zapisać je w tablicy, a następnie sprawdzić w bloku 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

Rozumiem, że "używanie ostrzeżeń" ma charakter leksykalny. Ale mój TestHelper.pm nie miał deklaracji "paczki". Czy jest jednoznaczne, kiedy przekazuję "-MTestHelper" przez PERL5OPTS? – Hissohathair

+3

Określenie zakresu leksykalnego nie ma nic wspólnego z pakietami. Biegnie od punktu deklaracji do końca pliku (lub końcowego nawiasu klamrowego, jeśli był wewnątrz nawiasów klamrowych). Nigdy nie wpływa na kod w innym pliku. – cjm

+0

Ah. Wspaniale dzięki. – Hissohathair