2009-06-23 64 views
3

我正在爲某些Perl腳本構建迴歸系統(而不是單元測試)。如何測試Perl程序從我的測試套件中編譯?

該系統的核心部件是

`perl script.pl @params 1>stdoutfile 2>stderrfile`; 

然而,在實際工作中的腳本過程中,他們有時不編譯(衝擊!)。但是perl本身會正確執行。但是,我不知道如何在stderr上檢測Perl是否無法編譯(因此寫入stderr),或者我的腳本在輸入時禁止(因此寫入stderr)。

如何檢測程序是否執行,但沒有詳盡地查找Perl錯誤消息並刷新stderr文件?

回答

6

這可能是最容易做的這兩個步驟:

system('$^X -c script.pl'); 
if ($? == 0) { 
    # it compiled, now let's see if it runs 
    system('$^X script.pl', @params, '1>stdoutfile', '2>stderrfile'); 
    # check $? 
} 
else { 
    warn "script.pl didn't compile"; 
} 

注意使用$^X,而不是perl。這更加靈活和強大。它可以確保您從同一個安裝中運行,而不是在您的路徑中首先顯示的任何解釋器。系統調用將繼承您的環境(包括PERL5LIB),因此產生不同版本的perl可能會導致難以診斷的兼容性錯誤。

+3

你應該總是使用$^X。幾乎每次使用它時,我都被一個硬編碼的'perl'咬了。問題是,子進程繼承你的PERL5LIB,這可能是錯誤的,在路徑中的第一個Perl。您最終會遇到奇怪的庫不匹配錯誤。 – 2009-06-24 17:03:34

+0

heh。這很醜陋。雖然它並不總是很重要(Windows用戶不太可能安裝多個版本的Perl),但使用$^X永遠不會有害。我會相應地更新答案。 – 2009-06-24 17:46:09

2

查看$?變量。

perldoc perlvar

由過去的管 關閉,反引號返回的狀態( 「``」)命令, 成功調用wait()或 waitpid函數(),或從系統( ) 運營商。這只是由 傳統Unix wait()系統調用 (或者看起來像它)返回的16位 狀態字。 因此,子 的出口值是真的( 「$?>> 8」),和 「$?& 127」 給出了一個信號,如果有的話, 過程經搶救無效死亡,而 「$?& 128」 報告是否存在覈心轉儲。

+0

但是否$?從* perl *或* script *返回結果Perl返回值是什麼 - 我在Google搜索時無法找到它。 – 2009-06-23 17:13:47

+0

它可能是。如果你想檢查腳本編譯,運行$`Perl的-c script.pl`而不是和測試? == 0. – 2009-06-23 18:15:31

3

當我要檢查程序編譯,我檢查它編譯:)

這是我投入噸/ compile.t與我的測試套件的其餘部分運行。如果腳本無法編譯,它將停止所有測試:「

 
use Test::More tests => 1; 

my $file = '...'; 

print "bail out! Script file is missing!" unless -e $file; 

my $output = `$^X -c $file 2>&1`; 

print "bail out! Script file does not compile!" 
    unless like($output, qr/syntax OK$/, 'script compiles'); 
3

腳本出了名難以測試。你必須運行它們,然後刮取它們的輸出。你不能單位測試他們的膽量......或者你能嗎?

#!/usr/bin/perl -w 

# Only run if we're the file being executed by Perl 
main() if $0 eq __FILE__; 

sub main { 
    ...your code here... 
} 

1; 

現在您可以像加載其他庫一樣加載腳本。

#!/usr/bin/perl -w 

use Test::More; 

require_ok("./script.pl"); 

你甚至可以運行和測試main()。 Test::Output便於捕捉輸出。你可以說local @ARGV控制參數,或者你可以改變的main()採取@ARGV作爲參數(推薦)。

然後就可以開始分裂的main()成更小的程序,你可以很容易地進行單元測試。