2010-04-13 24 views
5

Şu anda bakımını sürdürmemiz gereken ortamımızda bir Perl betiği var. Komut dosyası boyunca global değişkenleri kullanmak (ve yeniden kullanmak) dahil olmak üzere kötü uygulamalarla doludur. Senaryoda değişiklik yapmaya başlamadan önce, bazı test senaryoları yazmaya çalışacağım, böylece iyi bir regresyon tabanına sahip olacağım. Bunu yapmak için, bu page'da açıklanan bir yöntemi kullanacaktım.Bağımsız bir Perl komut dosyasını test ederken değişkenleri geçersiz kıl

Tek bir alt yordam için testler yazarak başlıyordum. Ben

require 'script_to_test.pl'; 

ve bütün senaryoyu yürütmek olmaz yapabilirsiniz

return 1 if (caller()); 

O yol, benim test komut: Ben test ediyorum script üst kısmına yakın biraz bu hattı koydu.

test etmek gidiyordu ilk altprogram komut boyunca ayarlanır küresel değişkenlerin kullanımı çok kolaylaştırır. Ben beyan nerede testi, üst kısmında büyük bir "my" bloğu vardır değilim, maalesef

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

(benim için) komut dosyası: My düşünce, benim test komut dosyasındaki böyle bir şey bu değişkenleri geçersiz kılmak için çalışmaktı komut dosyasında kullanılan tüm değişkenler. Bu, test betiğimin, testler üzerinde çalıştığım komut dosyasındaki değişkenleri görmesini/değiştirmesini önler.

Exporter, Test :: Mock ... ve diğer bazı modüller ile oynadım, ancak herhangi bir değişkeni değiştirmek isteyebileceğim gibi görünüyor. moda.

Amacım, diğer komut dosyasını değiştirmemek, ancak diğer komutları değiştirmeye başladığımda bazı iyi testler yapmak için, hiçbir şeyi kırmadığımdan emin olabilirim. Komut dosyası yaklaşık 10.000 satırdır (ana blokta 3.000). Bu yüzden, eğer bir şeyi değiştirmeye başlarsam, kodun diğer bölümlerini etkileyeceğim, bu yüzden iyi bir test paketine sahip olmanız yardımcı olacaktır.

Bu mümkün mü? Arama komut dosyası, "my" ile bildirilen başka bir komut dosyasındaki değişkenleri değiştirebilir mi?


Ve en iyi çözüm olabilir vs. "Sadece sıfırdan senaryoyu yeniden yazmak" gibi cevaplarla atlamak yok ama benim soruya cevap vermez ve lütfen Yeniden yazmak için zamanımız yok. komut (veya komut davranışını değiştirmeden bir fotoğraf eklenebilir varsa) bir package beyanı varsa

cevap

5

kapanışları varsa sen (anlamsal değişkenler tutmak istiyorsanız Onlarla inşa edilmiş) etrafında poke için modül PadWalker kullanabilirsiniz.

Test kodunda sonra
package somepackage; 

use PadWalker qw/peek_my/; 

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

our $lexpad = peek_my 0; 

:

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

Bu, orijinal komut dosyasında minimum değişikliklerle mükemmel şekilde çalışır. – BrianH

2

, o zaman bir our ilanına my beyanı değiştirmek ve tam değişken adını kullanarak değişkenleri değiştirebilir.

Eski komut dosyası:

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

Ve test komut:

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

Değişim için

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

eski komut bağımsız bir komut ise, bir paket adı eklemek için her zaman güvenlidir

eski kodunda böyle bir şey içerir ve değişkenleri kapsamak için 'bizim' kullanmak. – mob

+0

Betiğin paket bildirimi yok. Yine de bir tane eklemeyi deneyebilirim ... – BrianH

+0

Paket bildirimi olmadan (ama yine de '' '' '' '' 'ı değiştirerek), test komut dosyasından' $ main :: var_from_other_script' komutunu kullanabileceğinizi sanıyorum. – mob

İlgili konular