簡體   English   中英

Perl 的首選單元測試框架是什么?

[英]What is the preferred unit testing framework for Perl?

我對 Perl 有點陌生,我想知道是否有首選的單元測試框架?

Google 向我展示了一些不錯的結果,但由於我是新手,我不知道社區內是否有明確的偏好。

Perl 附帶了大量出色的測試工具! Perl 核心對其進行了數以萬計的自動檢查,並且在大多數情況下,它們都使用這些標准 Perl 框架。 它們都使用 TAP(測試任何協議)聯系在一起。

在 Perl 中創建 TAP 測試的標准方法是使用Test::More包系列,包括用於入門的Test::Simple 這是一個快速示例:

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 有大量其他函數可以讓測試其他東西更容易(字符串、正則表達式比較、深層結構比較),還有Test::Harness后端可以讓你測試大組單獨的測試腳本。

最重要的是,正如Schwern指出的那樣,幾乎所有現代Test::模塊都可以協同工作。 這意味着您可以將Test::Class (如Markus所指出的)與rjh答案中列出的所有優秀模塊一起使用 事實上,因為Test::Builder —— Test::More和其他工具所基於的工具(目前由 Schwern 維護......感謝 Schwern!)——如果需要,您可以從將與所有其他測試框架一起工作。 僅此一點就使 Perl 的 TAP 系統成為我認為最好的系統之一:一切都可以協同工作,每個人都使用相同的工具,您只需很少的額外工作就可以添加到框架中以滿足您的需求。

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 (通常從 shell 調用作為prove )按順序運行一系列測試,並獲得哪些測試通過或失敗的摘要。

Test::More 也可以做一些更復雜的事情,比如將測試標記為 TODO(不要期望它們通過,但為了以防萬一,運行它們)或 SKIP(這些測試已損壞/可選,不要運行它們)。 您可以聲明您希望運行的測試數量,因此如果您的測試腳本中途死亡,則可以檢測到這一點。

一旦您開始進行更復雜的測試,您可能會發現其他一些 CPAN 模塊很有用——這里有幾個例子,但還有很多(很多):

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

絕對從這個頁面開始: http : //perldoc.perl.org/Test/Simple.html並遵循Test::Tutorial的參考。

如果您練習 TDD,您會注意到您的單元測試集正在發生很多變化。 Test::Class遵循 xUnit 模式 ( http://en.wikipedia.org/wiki/XUnit )。

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

我也嘗試過單元測試的“perl-ish”方式(僅使用 Test::More),但我發現它有點老式和繁瑣。

一些反建議可能是有序的:

反推薦:

不要為 Perl 使用Test::Unit系列的測試包,例如Test::Unit::AssertTest::Unit::TestCases

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

Test::Unit、Test::Unit::TestCases、Test::Unit::Assert 工作得很好(當我在 2015-2016 年使用它們時)。 Test::Unit 應該沒有與 Perl 的測試任何協議 (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)這樣的特殊名稱is(VAL1,VAL2,TESTNAME)而不是像$test_object->assert_equals(VAL1,VAL2,TEST_ERR_MSG)這樣的 xUnit 樣式名稱。 Test::Class 確實具有自動檢測所有注釋為:Test 的令人愉快的功能,類似於 xUnit 和 TEST::Unit::TestCase 使用自省運行所有名為 test_* 的函數的方法。

但是,底層包Test::Builder是面向對象的,因此更具有 xUnit 風格。 不要被這個名字嚇跑——它不是一個工廠,它主要是一個帶有測試斷言方法的套件。 盡管大多數人繼承自它,但您可以根據需要直接調用它,例如$test_object->is(VAL1,VAL2,TESTNAME) ,並且通常您可以使用 Test::Builder 調用來解決程序包(如 Test)的限制:: 更多建立在 Test::Builder 之上——比如修復報告錯誤的調用堆棧級別。

Test::Builder 通常使用單例樣式,但您可以創建多個對象。 我不確定這些行為是否符合 xUnit 系列測試的預期。

到目前為止,沒有簡單的方法可以解決限制,例如 Perl TAP 測試使用 TEST_NAMES,每個斷言,沒有層次結構,並且不區分 TEST_NAMES 和 TEST_ERROR_MESSAGES。 (錯誤報告級別有助於彌補這一不足。)

可以創建一個適配器,使 Test::Builder 和 TAP 樣式測試更加面向對象,以便您可以基於 TAP 以外的其他東西(它記錄比 TAP 更有用的信息 - 據說像 ANT 的 XML 協議)。 我認為調整名稱和/或缺少的概念將涉及進入 Test::Builder 或自省。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM