2010-05-20 60 views
28

我對Perl很陌生,我想知道是否有一個優選的單元測試框架?什麼是Perl的首選單元測試框架?

谷歌正在向我展示了一些不錯的成績,但由於我是新來這個,我不知道是否有在社區內一個明顯的偏好。

回答

35

Perl擁有一套強大的測試工具! Perl核心對其進行了數萬次自動檢查,並且大部分都使用這些標準的Perl框架。他們都使用TAP綁定在一起 - Test Anything Protocol

在Perl創建TAP測試使用Test::More家庭套餐,包括入門的標準方法。這裏有一個簡單的例子:

use 5.012; 
use warnings; 

use Test::More tests => 3; 

my $foo = 5; 
my $bar = 6; 

ok $foo == 5, 'Foo was assigned 5.'; 
ok $bar == 6, 'Bar was assigned 6.'; 
ok $foo + $bar == 11, 'Addition works correctly.'; 

和輸出是:

ok 1 - Foo was assigned 5. 
ok 2 - Bar was assigned 6. 
ok 3 - Addition works correctly. 

從本質上講,上手,所有你需要做的就是把傳遞一個布爾值和一個字符串,解釋應該發生什麼!

一旦你完成了這一步,Test :: More就有了大量的其他功能,使測試其他事情變得更容易(字符串,正則表達式比較,深層結構比較),並且後端可以讓你測試大型各個測試腳本組合在一起。

最重要的是,作爲Schwern指出,幾乎所有的現代Test::模塊的協同工作。這意味着您可以使用Test::Class(如Markus指出)與rjhanswer中列出的所有優秀模塊一起使用。實際上,因爲Test::Builder - Test::More和其他構建的工具(現在由Schwern維護......感謝Schwern!) - 如果需要,您可以從頭開始構建自己的測試子例程,它將與所有其他測試框架。這本身就使Perl的TAP系統的最好的一個赫然出現在我的意見:一切工作在一起,每個人都使用相同的工具,你可以添加到框架,以滿足您的需求很少的額外工作。

+0

只是想知道什麼是'tests => 3'。我需要硬編碼的案件數量? – Mike 2010-05-20 17:45:02

+6

你不需要。但是如果你的測試腳本在輸出1或2個測試結果後就死掉了,Test :: More就知道你的測試失敗了(即使它出錯的代碼爲0)。你也可以在腳本的末尾使用Test :: More'no_plan''或者調用'done_testing()'。 – rjh 2010-05-20 17:46:49

+0

我無法找到使用無計劃的正確方法。如果我沒有給'done_testing'指定一個數字參數,我會得到'你試圖在沒有計劃的情況下運行測試!有一個計劃' – Mike 2010-05-20 17:58:27

13

Perl的最流行的測試「框架」是一個測試結果的格式被稱爲TAP(測試任何協議),這是一組字符串看起來像:

ok 1 - Imported correctly 
ok 2 - foo() takes two arguments 
not ok 3 - foo() throws an error if passed no arguments 

任何腳本,它可以產生這些字符串算作一個Perl測試。可以使用Test::More以生成用於各種條件TAP - 檢查變量是否等於值,檢查如果一個模塊正確導入,或者如果兩個結構(列/散列)是相同的。但在真正的Perl的精神,不止一種方法去做一件事,還有其他方法(如Test::Class,這看起來有點像JUnit的!)

測試腳本的一個簡單的例子(他們通常在.t結束,例如foo.t

use strict; 
use warnings; 
use Test::More tests => 3; # Tell Test::More you intend to do 3 tests 

my $foo = 3; 
ok(defined $foo, 'foo is defined'); 
is($foo, 3, 'foo is 3'); 
$foo++; 
is($foo, 4, 'incremented foo'); 

您可以使用Test::Harness(通常援引爲prove從shell)運行的一系列序列測試,並獲得其中的那些通過或失敗的總結。

測試::更多也可以做一些更復雜的東西,如標記測試TODO(不要期望它們通過,但運行它們以防萬一)或跳過(這些測試是打破/可選,不要運行它們)。您可以聲明您希望運行的測試數量,因此如果您的測試腳本中途死亡,則可以檢測到該數量。

一旦你開始做更復雜的測試,你可能會發現其他一些CPAN模塊有用的 - 這裏有幾個ecamples,但也有許多(許多)更多:

Test::Exception - 測試你的代碼拋出錯誤/不會引發任何錯誤
Test::Warn - 測試您的代碼是否生成警告
Test::Deep - 深入比較對象。他們不必是相同的 - 你可以忽略數組排序,使用正則表達式,忽略對象等類
Test::Pod - 確保你的腳本有POD(文檔),並且它是有效的
Test::Pod::Coverage - 確保您的POD文件的所有方法/在你的模塊功能
Test::DBUnit - 測試數據庫交互
Test::MockObject - 讓假裝對象來控制你的測試環境

5

如果你實踐TDD,你會發現,你的單元測試集正在改變很多。 Test::Class遵循xUnit模式(http://en.wikipedia.org/wiki/XUnit)。

對我來說,xUnit的主要好處是將每個測試封裝在方法中。該框架通過測試方法的名稱命名每個斷言,並增加在每次測試之前和之後運行設置和拆卸方法的可能性。

我已經嘗試了單元測試的「perl-ish」方式(也就是使用Test :: More),但是我發現它有點過時和繁瑣。

+1

我真的很喜歡Test :: Class。關於Test :: Class的簡潔之處在於它只是構建基於TAP的測試的另一種方式 - 另一種框架,將其從「Procedural」轉換爲「面向對象」。它將「如何將其報告」從「如何運行」中分離出來,讓您在Test :: Class對象中使用任何其他Test :: More樣式測試步驟/測試函數。但它不一定是基於TAP的測試 - 它只是非常擅長。您可以擴展Test :: Class並覆蓋很多默認行爲,並簡單地使用該框架。 – 2010-05-20 20:19:01

2

一些反建議可能是爲了:

反建議:

不要使用Test::Unit家庭測試包的Perl的,如Test::Unit::AssertTest::Unit::TestCases

原因:Test::Unit似乎被放棄。

Test :: Unit,Test :: Unit :: TestCases,Test :: Unit :: Assert work,very well(when I used them 2015-2016)。 Test :: Unit被認爲未與Perl的Test Anything Protocol(TAP)集成,儘管我發現這很容易修復。

但是Test :: Unit令人沮喪,因爲很多其他的Perl測試包,大部分是使用Test :: Builder構建的,比如Test :: More,Test :: Most,Test :: Exception,Test :: Differences, Test :: Deep,Test :: Warn等,不能很好地與Test :: Unit的面向對象測試方法交互。

一旦您調整了Test :: Unit以使用Test :: More和TAP,您就可以混合使用Test :: Unit測試和Test :: Builder測試;但這些其他軟件包的優點不適用於OO擴展。無論如何,這是使用xUnit風格測試的很多原因。

假設CPAN的Test::Class允許「以xUnit/JUnit風格輕鬆創建測試類」 - 但我不確定我可以推薦這一點。它看起來不像xUnit,而不是OO,像is(VAL1,VAL2,TESTNAME)這樣的特殊名稱,而不是像$test_object->assert_equals(VAL1,VAL2,TEST_ERR_MSG)這樣的xUnit樣式名稱。 Test :: Class具有自動檢測註釋的所有測試的令人愉快的功能:測試,與xUnit和TEST :: Unit :: TestCase使用內省運行所有名爲test_ *的函數的方法相當。

但是,底層包Test::Builder是面向對象的,因此更多的xUnit風格。不要被這個名字嚇倒 - 它不是工廠,它主要是一套測試斷言方法。雖然大多數人都是從它那裏繼承的,但是如果你願意的話,你可以直接打電話給他並且通常可以使用Test :: Builder調用來解決程序包(如Test :: Builder之上的Test :: More)的侷限性 - 例如修復報告錯誤的callstack級別。

Test :: Builder通常使用singleton樣式,但您可以創建多個對象。我不確定這些行爲是否像一個xUnit家族測試期望的那樣。

到目前爲止,沒有簡單的方法可以解決Perl TAP測試等限制使用TEST_NAMES,每個斷言,沒有層次結構,也沒有區分TEST_NAMES和TEST_ERROR_MESSAGES的限制。 (Err報告級別有助於減少缺陷)

可能會創建一個適配器,使Test :: Builder和TAP樣式測試更面向對象,這樣您就可以對TAP以外的其他事物進行重定位(記錄更多比TAP更有用的信息 - 據說像ANT的XML協議)。我認爲適應名稱和/或缺少的概念將涉及進入Test :: Builder或反思。

+0

謝謝彼得。更乾淨。當我使用老化軟件浪費時間時,我開始發泡。 – 2016-09-26 19:37:40