在没有构建的情况下测试分发中的脚本

时间:2013-01-27 05:19:09

标签: perl testing software-distribution

我正在尝试测试我在Perl发行版中包含的脚本。该脚本只输出到文件,因此我的测试在运行后检查文件内容。我尝试按照this帖子中的说明进行操作,但这对我来说并不适用。我正在测试的脚本在同一个发行版中使用一个模块,因此运行脚本需要以某种方式将模块的位置添加到@INC。我注意到Test::Script为参数添加了-Mblib,所以我尝试了同样的方法。但是,它在开发期间不起作用,因为没有blib目录。使用-Mblib可使所有内容仅在dzil testmake test下运行。在开发过程中,我使用prove或仅使用perl -Ilib t/test_script.pl,尝试使用-Mblib会导致测试失败并出现警告Cannot find blib even in C:\。考虑到这一点,我有几行代码缺少一个关键部分:

my $script_path = catfile( $FindBin::Bin, updir(), qw(scripts my_script.pl) );
my $include = 
    $HAS_BLIB && '-Mblib' || 
    '-I"' . catdir($FindBin::Bin, updir(), 'lib') . '"';
my $args = join ' ', map {qq["$_"]} @input_args;
my $command = qq{"$^X"  $include "$script_path" $args};
`$command`;
#test that script worked here...

我应该使用什么代替标量$HAS_BLIB?我需要一种方法来判断我是否正在构建发行版。 其他投入是受欢迎的。也许我有更好的方法来做这件事?我想要一种方法来测试同时使用provemake test传递的脚本。

2 个答案:

答案 0 :(得分:1)

要回答这个问题,您可以使用Module :: Path来检查分发中的任何模块文件是否在blib/lib目录中。这不是万无一失的,因为某人可能正在另一个名为prove的目录内的分发上运行blib,但我认为这不太可能。这样做的缺点是要求分发在某处有.pm个文件,但情况可能并非如此。

或者,您可以检查包含t目录的目录(在$Bin中的FindBin中的测试脚本中)是否具有blib目录它。但是,如果您在没有make的情况下运行make clean然后进一步开发了脚本,那么当您运行prove时,blib目录中的旧脚本仍会运行。< / p>

在我对我的问题的评论中,我提到了检查$INC{'blib.pm'}。这仅在使用-Mblib调用测试脚本时才有效,而make test不会执行此操作。相反,它会将ExtUtils::Command::MM::test_harnessblib/libblib/arch作为包含目录进行调用。

一旦你知道你正在运行blib代码,那么你需要更改包含路径(应该是blib/lib)和脚本路径(应该是blib/script/whatever(和如果您的脚本最初有一个,则不.pl,因为make删除了它。所以这是原始示例的正确版本:

use Module::Path 'module_path';
use Path::Tiny;
use FindBin;
use Test::More;
plan tests => 1;
use Capture::Tiny;
my $module_path = path(module_path('My::Thing'));
my $HAS_BLIB =
    $module_path        #Thing.pm
        ->parent    #My
        ->parent    #lib
        ->parent    #blib
        ->basename eq 'blib';
my $script_path = $HAS_BLIB && path(qw(blib script my_script)) ||
    path(path($FindBin::Bin)->parent, 'bin', 'my_script.pl');
my $include = $HAS_BLIB && '-Mblib' || # could also do -Iblib/lib -Iblib/arch
    '-I'. path(path($FindBin::Bin)->parent, 'lib'); # would use installed version of C code
my @command = ($^X, $include, $script_path, @batch_files);
my ($stdout, $stderr) = capture {system(@command)};
is($stderr, '', 'no errors reported from script');
#more tests here

这是一个非常麻烦的事情,在这种情况下,我不认为这是必要的。我不完全确定什么时候会有用。如果您的发行版具有C / C ++代码,那么您可能希望始终使用blib解决方案,这会将blib / arch添加到包含路径中。使用上面的简单示例,测试通过非blib设置传递,因为原始文件仍然可用。复制到blib目录中的文件几乎没有变化。因此,当我调试这个时,我能告诉它是否做正确的事情的唯一方法是打印出所用的完整命令!

换句话说,它不是非常可测试的,如果有人真的需要这个,那么他们应该创建一个模块来管理它(并测试它)。 Test::Script似乎总是使用-Mblib,这意味着你可能会使用过时的make结果,并且你必须传入脚本的路径,这意味着由你决定是否要使用原始脚本或blib/script内的脚本。

答案 1 :(得分:-1)

如果您只需要测试脚本是否已成功写入文件而不需要检查其内容,则可以在脚本中执行此操作。 Perl open,例如returns nonzero on successprint returns true if successful

捕获这些函数的返回值(或者您正在使用的任何函数),测试成功,并相应地设置脚本exit value,然后对其进行测试。