2009-08-30 18 views
12

Cuando ejecuto un conjunto de pruebas de aplicaciones, deseo promocionar todas las advertencias de Perl compilación y tiempo de ejecución (por ejemplo, la advertencia "Variable no inicializada") a errores fatales para que yo y los otros desarrolladores investiguen y corrijan el código que genera la advertencia. Pero solo quiero hacer esto durante el desarrollo y las pruebas de CI. En producción, las advertencias deberían permanecer como advertencias.¿Cómo debo promover las advertencias de Perl a errores fatales durante el desarrollo?

He intentado lo siguiente: En "T/lib" He creado un módulo de TestHelper.pm:

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

Y llamó el conjunto de pruebas de esta manera:

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

pero esto no tiene el efecto deseado de promover todas las advertencias a errores fatales. Recibí las advertencias como normales, pero las advertencias no parecían ser consideradas fatales. Tenga en cuenta que todos mis scripts test.t tienen la línea "use warnings"; en ellos - quizás esto sobrepasa el de TestHelper.pm porque "usar advertencias" tiene un alcance local?

En vez he hecho esto:

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

Esto funciona, pero tiene un olor código de ello. Tampoco me gusta que explote en la primera advertencia. Prefiero que la serie de pruebas se ejecute en su totalidad, registrando todas las advertencias, pero que el estado de la prueba finalmente falló porque el código se ejecutó con advertencias.

¿Hay alguna manera mejor de lograr este resultado final?

Respuesta

21

Creo que estás buscando Test::NoWarnings.

+0

Ese módulo es exactamente lo que necesito, gracias. Sabes que funciona más o menos lo mismo que friedo sugiere más arriba. :-) – Hissohathair

+0

Desafortunadamente Test :: NoWarnings aún no funciona correctamente con "done_testing()", consulte https://rt.cpan.org/Public/Bug/Display.html?id=66485 y https: // rt. cpan.org/Ticket/Display.html?id=52412 –

17

El motivo use warnings FATAL => qw(all); no funciona para usted porque use warnings tiene un alcance léxico. Entonces cualquier advertencia producida dentro de TestHelper.pm sería fatal, pero las advertencias producidas en otro lugar funcionarán normalmente.

Si desea habilitar las advertencias fatales a nivel mundial, creo que un controlador $SIG{__WARN__} es probablemente la única forma de hacerlo. Si no desea que explote en la primera advertencia, puede dejar que su controlador los almacene en una matriz y luego verificarlo en un bloque 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

Entiendo que "use advertencias" tiene un alcance léxico. Pero mi TestHelper.pm no tenía una declaración de "paquete". ¿Está implícito uno cuando paso "-MTestHelper" a través de PERL5OPTS? – Hissohathair

+3

El alcance léxico no tiene nada que ver con los paquetes. Se ejecuta desde el punto de declaración hasta el final del archivo (o la llave de cierre final, si estaba dentro de llaves). Nunca afecta el código en otro archivo. – cjm

+0

Ah. Excelente, gracias. – Hissohathair

Cuestiones relacionadas