Me tomó un tiempo y también me tomó tomar pequeños fragmentos de varias fuentes diferentes y fusionarlos, pero creo que tengo un pequeño ejemplo de trabajo que demuestra suficientemente a un novato de Perl el proceso de compilación de Perl, incluidas las pruebas unitarias y la cobertura de código análisis e informes. (Estoy usando ActiveState ActivePerl v5.10.0 en una PC con Windows XP Pro, Module :: Build , Test :: More , Devel :: Cover )
Comience con un directorio para su proyecto Perl y luego cree un directorio "lib" y un directorio "t" en el directorio de su proyecto:
HelloPerlBuildWorld
|
|----------> lib
|
|----------> t
En el directorio "lib", cree un archivo de texto llamado "HelloPerlBuildWorld.pm". Este archivo es su módulo Perl que estará construyendo y probando. Pegue el siguiente contenido en este archivo:
use strict;
use warnings;
package HelloPerlBuildWorld;
$HelloPerlBuildWorld::VERSION = '0.1';
sub hello {
return "Hello, Perl Build World!";
}
sub bye {
return "Goodbye, cruel world!";
}
sub repeat {
return 1;
}
sub argumentTest {
my ($booleanArg) = @_;
if (!defined($booleanArg)) {
return "null";
}
elsif ($booleanArg eq "false") {
return "false";
}
elsif ($booleanArg eq "true") {
return "true";
}
else {
return "unknown";
}
return "Unreachable code: cannot be covered";
}
1;
En el directorio "t", cree un archivo de texto llamado "HelloPerlBuildWorld.t". Este archivo es su secuencia de comandos de prueba unitaria que intentará probar completamente su módulo Perl anterior. Pegue el siguiente contenido en este archivo:
use strict;
use warnings;
use Test::More qw(no_plan);
BEGIN { use_ok('HelloPerlBuildWorld') };
require_ok( 'HelloPerlBuildWorld' );
my $helloCall = HelloPerlBuildWorld::hello();
like($helloCall, qr/Hello, .*World/, "hello() RE test");
is($helloCall, "Hello, Perl Build World!", "hello() IS test");
for (my $ctr=1; $ctr<=10; $ctr++) {
my $repeatCall = HelloPerlBuildWorld::repeat();
is($repeatCall, 1, "repeat() IS test");
}
my $argumentTestCall1 = HelloPerlBuildWorld::argumentTest();
is($argumentTestCall1, "null", "argumentTest() IS null test");
my $argumentTestCall2 = HelloPerlBuildWorld::argumentTest("true");
is($argumentTestCall2, "true", "argumentTest() IS true test");
my $argumentTestCall3 = HelloPerlBuildWorld::argumentTest("false");
is($argumentTestCall3, "false", "argumentTest() IS false test");
my $argumentTestCall4 = HelloPerlBuildWorld::argumentTest(123);
is($argumentTestCall4, "unknown", "argumentTest() IS unknown test");
Ahora haga una copia de seguridad en el directorio de su proyecto de nivel superior, cree un archivo de texto llamado "Build.PL". Este archivo creará sus scripts de compilación que usará más adelante. Pegue el siguiente contenido en este archivo:
use strict;
use warnings;
use Module::Build;
my $builder = Module::Build->new(
module_name => 'HelloPerlBuildWorld',
license => 'perl',
dist_abstract => 'HelloPerlBuildWorld short description',
dist_author => 'Author Name <[email protected]>',
build_requires => {
'Test::More' => '0.10',
},
);
$builder->create_build_script();
Esos son todos los archivos que necesita. Ahora, desde la línea de comando en el directorio del proyecto de nivel superior, escriba el siguiente comando:
perl Build.PL
Verá algo similar a lo siguiente:
Checking prerequisites...
Looks good
Creating new 'Build' script for 'HelloPerlBuildWorld' version '0.1'
Ahora debería poder ejecutar sus pruebas unitarias con el siguiente comando:
Build test
Y vea algo similar a esto:
Copying lib\HelloPerlBuildWorld.pm -> blib\lib\HelloPerlBuildWorld.pm
t\HelloPerlBuildWorld....ok
All tests successful.
Files=1, Tests=18, 0 wallclock secs ( 0.00 cusr + 0.00 csys = 0.00 CPU)
Para ejecutar sus pruebas unitarias con análisis de cobertura de código, intente esto:
Build testcover
Y verá algo en el orden de esto:
t\HelloPerlBuildWorld....ok
All tests successful.
Files=1, Tests=18, 12 wallclock secs ( 0.00 cusr + 0.00 csys = 0.00 CPU)
cover
Reading database from D:/Documents and Settings/LeuchKW/workspace/HelloPerlBuildWorld/cover_db
----------------------------------- ------ ------ ------ ------ ------ ------
File stmt bran cond sub time total
----------------------------------- ------ ------ ------ ------ ------ ------
D:/Perl/lib/ActivePerl/Config.pm 0.0 0.0 0.0 0.0 n/a 0.0
D:/Perl/lib/ActiveState/Path.pm 0.0 0.0 0.0 0.0 n/a 0.0
D:/Perl/lib/AutoLoader.pm 0.0 0.0 0.0 0.0 n/a 0.0
D:/Perl/lib/B.pm 18.6 16.7 13.3 19.2 96.4 17.6
...
[SNIP]
...
D:/Perl/lib/re.pm 0.0 0.0 0.0 0.0 n/a 0.0
D:/Perl/lib/strict.pm 84.6 50.0 50.0 100.0 0.0 73.1
D:/Perl/lib/vars.pm 44.4 36.4 0.0 100.0 0.0 36.2
D:/Perl/lib/warnings.pm 15.3 12.1 0.0 11.1 0.0 12.0
D:/Perl/lib/warnings/register.pm 0.0 0.0 n/a 0.0 n/a 0.0
blib/lib/HelloPerlBuildWorld.pm 87.5 100.0 n/a 83.3 0.0 89.3
Total 9.9 4.6 2.8 11.3 100.0 7.6
----------------------------------- ------ ------ ------ ------ ------ ------
Writing HTML output to D:/Documents and Settings/LeuchKW/workspace/HelloPerlBuildWorld/cover_db/coverage.html ...
done.
(Alguien, por favor, dígame cómo configurar Cover para ignorar todas las bibliotecas de Perl excepto y solo informarme sobre mi único archivo que escribí. ¡No pude hacer que el filtrado de Cover funcione de acuerdo con la documentación de CPAN!)
Ahora, si actualiza su directorio de nivel superior, puede ver un nuevo subdirectorio llamado "cover_db". Vaya a ese directorio y haga doble clic en el archivo "coberturas.html" para abrir el informe de cobertura del código en su navegador web favorito. Le brinda un buen informe de hipertexto codificado por colores donde puede hacer clic en el nombre de su archivo y ver estadísticas detalladas de cobertura, rama, condición y subrutina para su módulo Perl allí mismo en el informe junto al código fuente real. Puede ver en este informe que no cubrimos la rutina "bye ()" en absoluto y también hay una línea de código inalcanzable que no se cubrió como esperábamos.
(fuente: leucht.com )
Una cosa más que puede hacer para ayudar a automatizar este proceso en su IDE es crear más archivos de tipo "Build.PL" que realicen explícitamente algunos de los objetivos de compilación que hicimos anteriormente de forma manual desde la línea de comandos. Por ejemplo, uso un archivo "BuildTest.PL" con el siguiente contenido:
use strict;
use warnings;
use Module::Build;
my $build = Module::Build->resume (
properties => {
config_dir => '_build',
},
);
$build->dispatch('build');
$build->dispatch('test');
Luego configuré mi IDE para ejecutar este archivo (a través de "perl BuiltTest.PL") con un solo clic del mouse y automáticamente ejecuta mi código de prueba de unidad desde el IDE en lugar de hacerlo yo manualmente desde la línea de comando. Reemplace "dispatch ('test')" por "dispatch ('testcover')" para la ejecución automatizada de la cobertura del código. Escriba "Ayuda de compilación" para obtener una lista completa de los objetivos de compilación que están disponibles en Module :: Build.
Build build
y luegoBuild test
?$ENV{HARNESS_PERL_SWITCHES}
. Por ejemplo:-MDevel::Cover=+ignore,.t$,+inc,/app/lib,-select,MyModule.pm
dónde/app/lib
está la biblioteca privada de la aplicación yMyModule.pm
el módulo que se está probando.En respuesta a Kurt, propondría esta alternativa a su script BuiltTest.PL.
use strict; use warnings; use Module::Build; my $build = Module::Build->resume ( properties => { config_dir => '_build', }, ); $build->dispatch('build'); $build->dispatch('test');
Reutiliza la base de datos construida por Build.PL (y por lo tanto asume que ya se ejecutó).
fuente
Cubro esto en Perl intermedio así como en Mastering Perl . Kurt, sin embargo, ha dado un buen resumen.
Sin embargo, combino todo esto en un script de lanzamiento usando Module :: Release . Escribo un comando y todo sucede.
fuente
Lo fantásticamente útil
module-starter
genera un proyecto esqueleto fácil de usar que maneja la instalación de módulos, la creación de documentación y un buen diseño para que los archivos de los módulos vivan y, creo , soporte de cobertura de código. En mi opinión, es un gran comienzo para cualquier esfuerzo relacionado con el módulo Perl.Además: usar herramientas relacionadas con CPAN como
Module::Build
, incluso para módulos que probablemente nunca se lanzarán públicamente, es una muy buena idea .fuente
(divulgación: soy el autor)
Una vez que tenga todo ordenado como se describe anteriormente, puede dar el siguiente paso y usar Devel :: CoverX :: Covered para, por ejemplo,
Consulte la sinopsis para ver ejemplos concretos de líneas de comandos.
En Devel :: PerlySense hay soporte de Emacs para mostrar la información de cobertura en el búfer del código fuente ( captura de pantalla ) y para navegar hacia / desde los archivos de prueba de cobertura.
fuente