2010-04-13 79 views
5

我們現在需要維護的環境中有一個Perl腳本。它充滿了不好的做法,包括在整個劇本中使用(和重新使用)全局變量。在開始對腳本進行更改之前,我將嘗試編寫一些測試腳本,以便我可以擁有一個良好的迴歸基礎。要做到這一點,我要使用這個page上描述的方法。測試獨立Perl腳本時覆蓋變量

我是從編寫單個子程序的測試開始的。我把這個線有點接近腳本頂部我測試:

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()); 

不幸的是(對我來說),劇本我測試的頂部有一個巨大的「我」塊,它聲明腳本中使用的所有變量。這可以防止我的測試腳本查看/更改我正在運行測試的腳本中的變量。

我已經與出口商,測試::模擬...和其他一些模塊,但它看起來像是如果我想要改變任何變量我將不得不修改其他腳本在一些時尚。

我的目標是不改變其他腳本,但爲了得到一些好的測試運行,所以當我開始改變其他腳本時,我可以確保我沒有破壞任何東西。該腳本大約有10,000行(其中主要塊中有3,000行),所以我擔心如果我開始改變事情,我會影響代碼的其他部分,因此擁有一個好的測試套件會有所幫助。

這可能嗎? 調用腳本可以在用「my」聲明的另一個腳本中修改變量嗎?


請不要用類似的答案跳,「只是重新從頭開始寫劇本」等,這可能是最好的解決辦法,但它並沒有回答我的問題,並我們沒有時間/資源來重寫。

回答

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; 
+0

這可以很好地工作,只需對原始腳本進行最小限度的更改即可。 – BrianH 2010-04-13 15:49:02

2

如果腳本有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(); 
+2

如果舊的腳本是一個單獨的腳本,它始終是安全的,添加一個包名並使用'我們'來確定變量的範圍。 – mob 2010-04-13 15:34:40

+0

該腳本沒有包聲明。我可能會嘗試添加一個... – BrianH 2010-04-13 15:36:27

+0

沒有包聲明(但仍然在更改'my' - >'our'),我懷疑你可以在測試腳本中操作'$ main :: var_from_other_script'。 – mob 2010-04-13 15:47:49