如何从hg repo中安装的库中隔离出来进行测试?

Gan*_*ang 12 perl

如何使用本地hg repo库来测试已安装的libs的隔离?

安装生产的perl包和本地hg repo具有相同的结构

    +-- lib
        |-- modA.pm
        |-- modB.pm
    +-- bin
        |-- example.pl
    +-- t
        |-- modA.t
        |-- modB.t
Run Code Online (Sandbox Code Playgroud)

安装在库中,并将路径添加到@ PERL5

/nfs_share/perl/
env|grep -i perl
PERL5:/usr/local/perl:/nfs_share/perl
Run Code Online (Sandbox Code Playgroud)

当地的hg回购:

/data/user/hg/perl
Run Code Online (Sandbox Code Playgroud)

modB.pm

#!/usr/bin/perl
use modA;
sub modB_compare{
    my (x,y) = @_;
    # .....
    return x-y;
}
Run Code Online (Sandbox Code Playgroud)

斌/ example.pl

use FindBin qw($Bin);
use lib "${Bin}/lib/";
use modA, modB;
# if this call is from local lib
my $result = modB_compare(x,y);
# if sub being called from production or local hg?
my $result2 = modA_method();
# from local hg repo or from production lib?!
Run Code Online (Sandbox Code Playgroud)

如果我要在本地hg repo中进行修改和测试,那么我没有保证我调用的lib来自本地仓库,而不是来自生产库.

什么是隔离库的可能解决方案在本地hg repo中进行测试?

use*_*889 3

简短的回答:对于测试,只需使用prove -l.

如果我要在本地 hg 存储库中进行修改和测试,则无法保证我调用的库来自本地存储库,而不是来自生产库。

实际上,对于您定义的问题,是存在的。

如果您知道./lib/modA.pm存在并且./lib/位于@INC,则将./lib/modA.pm被加载并且任何系统perl版本都不会*。

您的use lib语句为您执行此操作,如perlvar @INCrequire中所述。

然而,对于测试,通常的做法是使用use lib,而是使用perl -I( ) 中的标志perl -Ilib t/modA.t或者更好的是,使用 Prove,它也有一个-l标志,所以你可以这样做,它会运行使用 中的模块的prove -l所有测试。t/./lib

注意:您可能还想研究ExtUtils::MakeMakerModule::Build::Tiny来帮助完成分发任务,并且您可能想考虑Dist::Zilla或(为了更快开始)Dist::Milla

如果您只是想验证发生了什么,您可以通过查看%INC检查哪些文件已加载use或语句。require

如果您绝对必须控制哪些模块是可访问的,例如因为您想根据是否安装了第三方模块(而不是您自己的代码)来测试不同的行为,我建议您查看perlbrew。这将帮助您编译自己的 perl(几乎任何最近的版本),它不使用系统 perl 中的库,而是拥有自己的库,使用local::lib; 然后您可以在多个已安装的 perls 之间切换。唯一的例外是与 perl 本身一起打包的库;您可以从Module::Corelist获取这些列表。

最后,您可能想看看Carton。我不认为这完全是您所要求的,但这是一个非常相似的问题领域,我认为值得一提。


* 好吧,严格来说,lib必须出现在系统 perl lib 目录@INC 之前,因为发生的情况是 perl按顺序遍历 @INC并找到与您要求其加载的包名称相对应的文件;您使用过的以及我在这个答案中讨论的所有方法将确保您的lib目录出现在@INC系统 perl 库的较早位置。