繁体   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