2011-08-01 25 views
1

我目前正在學習單元測試。爲此,我正在寫一個腳本,併爲整個腳本創建單元測試。到目前爲止事情進展順利,但我試圖測試從命令行輸入腳本的不正確數據觸發幫助信息。如何用Try :: Tiny「捕捉」Perl腳本中的pod2usage出口?

我的代碼看起來是這樣的:

sub getContext{ 
    my ($help) = @_; 

GetOptions(
    help|h => \$help, 
    ... 

pod2usage if $help; 
... 
} 

我的測試看起來像:

my $help_exception = 0; 
try{ 
    getContext({help => 0}); 
}catch{ 
$help_exception = 1; 
} 

ok($help_exception, "Script died correctly when given help flag"); 

我的輸出看起來非常相似:

1..4 

ok 1 - use scripts::scriptname; 

ok 2 

ok 3 

# Looks like you planned 4 tests but ran 3. 

# Looks like your test exited with 1 just after 3. 

幫助標誌的測試是測試4,它看起來像我的腳本正在退出而不觸發Try :: Tiny try catch塊。有沒有辦法解決這個問題,還是應該以不同的方式寫我的測試?

回答

4

Pod::Usage的文檔爲-exitval參數顯示如何阻止它們一起退出。你可以簡單地使用它並相應地調整你的代碼和/或測試。

否則,exit也不例外,並且因此不象可捕獲的異常。但是,它可以通過CORE::GLOBAL::exit覆蓋。假設你正確定位你的修改,使用這是一個合理的方法。

或者,你總是可以啓動一個子進程來運行你的整個腳本並捕獲它的功能,根據你的測試,完全避免Pod::Usage調用exit的問題。

在一個相關的說明,您使用的是測試Try::Tiny的方式有點奇怪。我相信使用Test::Fatal(這是基於Try::Tiny)可能使在未來更清晰的測試。

+0

非常感謝你的迴應,你會如何本地化CORE :: GLOBAL :: EXIT覆蓋? – Moses

+0

使用「本地」內置。 – rafl

2

的問題是,pod2usageexit,而不是拋出異常。我不認爲這可以被捕獲。

爲什麼不叫測試整個腳本並檢查返回值/輸出與您的期望?

1

由於BVR回答:程序/腳本是不是真的單元測試,因爲它不是由可重複使用的部件/單位。你應該全面測試它。用命令行參數執行它並檢查它的輸出和錯誤。例如,使用Capture::Tiny

use warnings; 
use strict; 
use Capture::Tiny qw(capture); 
use Test::More; 

my $script = "/bin/ls"; 

plan skip_all => "Have no `$script` to check" 
    unless -x $script; 

my ($out, $err) = capture { 
    system($script, "-1", "/"); 
}; 

like($out, qr{^bin$}m, "$script finds bin"); 
ok(! $err, "...without error"); 

done_testing(2); 

輸出prove

/home/apv/ab .. 
ok 1 - /bin/ls finds bin 
ok 2 - ...without error 
1..2 
ok 
All tests successful. 
+0

我正在使用modulino方法來測試腳本。這允許我在測試中使用mock,這對於我正在編寫的腳本(數據庫訪問,配置文件訪問等)而言是必需的。 http://www252.pair.com/comdog/mastering_perl/Chapters/18.modulinos.html – Moses