在测试独立的Perl脚本时覆盖变量

时间:2010-04-13 14:52:48

标签: perl testing

我们现在需要维护一个Perl脚本。它充满了不良做法,包括在整个脚本中使用(和重用)全局变量。在我开始更改脚本之前,我打算尝试编写一些测试脚本,这样我就可以获得良好的回归基础。为此,我将使用此page中描述的方法。

我开始编写单个子程序的测试。我把这行放在我正在测试的脚本顶部附近:

return 1 if ( caller() );

那样,在我的测试脚本中,我可以

require 'script_to_test.pl';

并且它不会执行整个脚本。

我要测试的第一个子程序充分利用了整个脚本中设置的全局变量。我的想法是尝试在我的测试脚本中覆盖这些变量,如下所示:

require_ok('script_to_test.pl');
$var_from_other_script = 'Override Value';
ok( sub_from_other_script() );

不幸的是(对我来说),我正在测试的脚本在顶部有一个巨大的“我的”块,它声明了脚本中使用的所有变量。这可以防止我的测试脚本看到/更改我正在运行测试的脚本中的变量。

我玩过Exporter,Test :: Mock ......以及其他一些模块,但看起来如果我想能够改变任何变量,我将不得不以某种方式修改其他脚本

我的目标是不更改其他脚本,但要运行一些好的测试,所以当我开始更改其他脚本时,我可以确保没有破坏任何内容。脚本是大约10,000行(主要块中有3,000行),所以我担心如果我开始更改内容,我会影响代码的其他部分,所以拥有一个好的测试套件会有所帮助。

这可能吗? 调用脚本是否可以修改使用“my”声明的另一个脚本中的变量?


请不要回答“只是从头开始重写脚本”等答案。这可能是最好的解决方案,但它没有回答我的问题,我们不知道t有重写时间/资源。

2 个答案:

答案 0 :(得分:5)

如果你想保持变量词法(如果有用它们构建的闭包)你可以使用模块PadWalker来解决。

在旧代码中包含类似的内容:

package somepackage;

use PadWalker qw/peek_my/;

my $x = 1;
# big my block declaration...

our $lexpad = peek_my 0;

然后在你的测试代码中:

${ $somepackage::lexpad->{'$x'} } = 2;

答案 1 :(得分:3)

如果脚本具有package声明(或者如果您可以在不更改脚本行为的情况下添加声明),则可以将my声明更改为our声明,并使用完全限定的变量名更改变量。

旧脚本:

my($a,@b,$c,%d);

更改为:

package Some::Package;
our($a,@b,$c,%d);

在你的测试脚本中:

sub_from_other_script();
$Some::Package::c = 42;
$Some::Package::d{$key} = $value;
sub_from_other_script();