2016-11-13 17 views
10

當Test :: More比較像arrayrefs和hashrefs彼此時,相應的診斷消息是非常有用的,並顯示結構不同的第一個索引,無論嵌套深度如何。但是,在將arrayref或hashref與簡單標量進行比較時,它會在診斷消息中生成字符串標量(帶有內存地址和引用類型),這很難解釋。Test :: More is_deeply在與字符串比較時不會很漂亮地打印數組/字符串

有沒有一種方法來配置Test :: More以漂亮的打印陣列或hashrefs以自定義的方式(如使用Data :: Dumper)?

下面是兩個測試用例的示例。第一個給你一些洞察你的程序中出現的內容,但意想不到的。第二個通知用戶字符串和arrayref之間的類型不匹配,但不打印arrayref中的任何項目。

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Test::More tests => 2; 

is_deeply(
    { 
     a => [5], 
    }, 
    { 
     a => [5, 6, 8], 
    }, 
    'compare two hashrefs structurally (very informative output)', 
); 

is_deeply(
    [5, 6, 8], 
    "", 
    'compare two "incompatible" values structurally (uninformative output)', 
); 

和抽頭輸出:

1..2 
not ok 1 - compare two hashrefs structurally (very informative output) 
# Failed test 'compare two hashrefs structurally (very informative output)' 
# at test-more-failure.pl line 6. 
#  Structures begin differing at: 
#   $got->{a}[1] = Does not exist 
#  $expected->{a}[1] = '6' 
not ok 2 - compare two "incompatible" values structurally (uninformative output) 
# Failed test 'compare two "incompatible" values structurally (uninformative output)' 
# at test-more-failure.pl line 16. 
#  Structures begin differing at: 
#   $got = ARRAY(0x7fe66b82cde8) 
#  $expected = '' 
# Looks like you failed 2 tests of 2. 

綜觀is_deeply在測試執行::更多,似乎沒有要的方式來使用自定義美化打印機或配置冗長的模塊。至少沒有一點對我來說很明顯。

這裏是當我們比較的參考和非參考會發生什麼:

https://metacpan.org/source/EXODIST/Test-Simple-1.302062/lib/Test/More.pm#L1121

好像被調用_format_stack({vals => [...]})代替_format_stack(...)

https://metacpan.org/source/EXODIST/Test-Simple-1.302062/lib/Test/More.pm#L1139

回答

9

TL;博士根據具體情況使用is_deeply($this, $that) || diag explain $this

嗨。 I'm the one to blame for is_deeply。它故意設計成在出現故障時不會吐出一個潛在的巨大數據結構。相反,它停在第一個區別。出於這個原因,你可能不希望全局使is_deeply轉儲它的參數。如果類型錯誤,如果你期望蘋果並且得到了斑馬,那麼知道多少斑馬和它們的生活故事就沒有多少意義。

有沒有支持的方式來改變它的診斷,抱歉,這是不可能的。 Test :: More正在被Test2替代。 Test :: More已經在Test2之上實現了,但是由於向後兼容的原因沒有利用它的特性。

您可以使用Test2::Bundle::More更直接地訪問Test2的功能,但它不是100%兼容的,並且它顯示與is_deeply相似。然而,它更加靈活,你可能想出一個方法來改變它的診斷行爲。看看Test2::Compare


回到你的問題......通過個案的基礎上的情況下,使用explainexplain使用正確配置的Data :: Dumper轉儲數據結構。由於Test :: More函數返回它們是否通過或失敗,因此可以編寫is_deeply($this, $that) || diag explain $this。例如...

my $stuff = [5, 6, 8]; 
is_deeply $stuff, "" || diag explain $stuff; 

not ok 2 
# Failed test at /Users/schwern/tmp/test.plx line 17. 
#  Structures begin differing at: 
#   $got = ARRAY(0x7f80b3803078) 
#  $expected = '' 
# [ 
# 5, 
# 6, 
# 8 
# ] 

diag是你如何打印故障診斷(這是打印到STDERR更禮貌的方式)。

1

嘗試eq_or_diff($got, $expected, $message)Test::Differences,它會打印出您的數據結構的一個美麗的表示,並清楚地突出確切的相似之處和差異。

+0

如果你想要一個數據結構的並排比較,這真的很不錯。但是,如果您正在開發,並且數據結構發生了變化,您只需要替換測試模塊中的定義,則'diag explain $ got'可以提供更容易的複製和粘貼輸出。 – Randall