我正在尝试测试包含在我的 Perl 发行版中的脚本。该脚本仅输出到文件,因此我的测试在运行后检查文件内容。我尝试按照 this 中的说明进行操作发布,但它对我来说不太管用。我正在测试的脚本使用同一发行版中的模块,因此运行脚本需要以某种方式将模块的位置添加到 @INC
。我注意到 Test::Script将 -Mblib
添加到参数中,所以我尝试了同样的方法。但是,它在开发过程中不起作用,因为没有 blib 目录。使用 -Mblib
使一切仅在 dzil test
或 make 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
?我需要一种方法来判断我是否正在构建发行版。
欢迎其他输入。也许我有更好的方法去做这件事?我只是想要一种方法来测试通过 prove
和 make test
的脚本。
最佳答案
要回答这个问题,您可以使用 Module::Path 检查分发中的任何模块文件是否在 blib/lib
目录中。这并非万无一失,因为有人可能正在另一个名为 blib
的目录中的分发版上运行 prove
,但我认为这不太可能。这也有一个缺点,即要求分发版在某处有一个 .pm
文件,但实际情况可能并非如此。
或者,您可以检查目录是否包含 t
目录(在测试脚本中,这将是来自 FindBin
的 $Bin
) 中有一个 blib
目录。但是,如果您在没有使用 make clean
的情况下运行 make
然后进一步开发脚本,当您运行 prove
时 中的陈旧脚本>blib
目录仍将运行。
在我对我的问题的评论中,我提到检查 $INC{'blib.pm'}
。这仅在使用 -Mblib
调用测试脚本时有效,而 make test
不这样做。相反,它调用 ExtUtils::Command::MM::test_harness
以 blib/lib
和 blib/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
中的脚本。
关于perl - 无需构建即可在分发中测试脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14544674/