簡體   English   中英

Perl,字符串,浮點數,單元測試和regexps!

[英]Perl, strings, floats, unit testing and regexps!

好吧,作為序言,這個問題可能比我正常的問題更“愚蠢” - 但是這個問題在過去的幾天一直讓我討厭,所以無論如何我都會問它。 我將舉例說明我的問題是什么,所以我希望將其概括為我當前的問題。

#!/usr/bin/perl -w use strict;

use Test::More 'no_plan';

my $fruit_string = 'Apples cost $1.50';
my ($fruit, $price) = $fruit_string =~ /(\w+)s cost \$(\d+\.\d+)/;

# $price += 0; # Uncomment for Great Success
is ($price, 1.50, 'Great Success');

現在,當這個運行時,我得到了消息

#   Failed test 'Great Success'
#          got: '1.50'
#     expected: '1.5'

為了使測試工作 - 我要么取消注釋注釋行,要么使用is ($price, '1.50', 'Great Success') 這兩個選項對我都不起作用 - 我正在使用Test :: Deep和cmp_deeply測試大量嵌套數據。 我的問題是,如何從正則表達式中提取雙精度然后立即將它作為雙精度使用 - 或者如果有更好的方法讓我知道 - 並隨意告訴我從事園藝或其他事情,學習Perl是硬。

您已經在使用Test :: Deep,因此您可以簡單地使用num()包裝器來執行數字而不是逐字符串比較(它甚至允許您添加容差,以比較兩個不精確的浮點值):

cmp_deeply(
    $result,
    {
        foo         => 'foo',
        bar         => 'blah',
        quantity    => 3,
        price       => num(1.5),
    },
    'result hash is correct',
);

對於單獨進行的正常比較, cmp_ok將起作用,但num()仍然可用: cmp_deeply($value, num(1.5), 'test name')仍然有效。

強制$price被解釋為數字:

is ( 0 + $price, 1.50, 'Great Success');

為什么不使用經過驗證的ok 您會測試你實際上意味着測試,而不必擔心是否件事is做什么太微妙或太聰明了。

ok($price == 1.5, 'Great Success');

is不提供故障一些額外的診斷,但是這是很容易與做ok ,太

ok($price == 1.5, 'Great Success') or diag("Expected \$price==1.5, got $price");

您的測試失敗,因為is($x, $y, $name)等同於cmp_ok($x, 'eq', $y, $name) eq強制將其每個參數計算為字符串。 既然你想要數字相等,你可以使用'=='cmp_ok寫出來。 您可以通過編寫自己的數字版本來簡化is

sub is_num {cmp_ok $_[0], '==', $_[1], $_[2]}

但是那個版本被巧妙地打破了,它會在錯誤的行上報告錯誤。 要確保錯誤報告顯示正確的行:

sub is_num {splice @_, 1, 0, '=='; goto &cmp_ok}

goto &sub的原因是因為cmp_ok使用caller來確定錯誤發生的位置。 goto &sub語法刪除了is_num的調用幀設置,以便cmp_ok認為從is_num的位置is_num它。

最后,我的模塊Test :: Magic的插件為Test::More提供了語法糖:

use Test::Magic 'no_plan';

... # setup code

test 'fruit price',
  is $price == 1.50;

這被解釋為cmp_ok( $price, '==', 1.50, 'fruit price')

這種行為的原因是使用eq進行比較,這會強制其參數的字符串化。 1.50字符串化為'1.5',這會失敗。

您的選擇是與行為(強制字符串化或數字化)一起生活,或者編寫您自己的替代方案,如果雙方在回到eq比較之前看起來像是數字,那么將在數字上進行比較。 我個人會采用后一種方法。

暫無
暫無

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

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