我可以在Test :: More的cmp_ok中使用智能匹配~~吗?

时间:2010-10-11 14:06:32

标签: perl testing smartmatch

我正在测试一个返回数组的函数。根据环境,数组可能会有所不同,但它总是至少有一个常量值(我要测试的值)。

当我使用Perl 5.12时,我可以使用smartmatch运算符来查找元素是否在数组中:

ok($known_value ~~ @returned, 'testing method abc')

但我喜欢islike的增强输出以及“找到”和“预期”部分。所以我尝试了这个:

cmp_ok($known_value, '~~', @returned, 'testing method abc')

这不起作用,因为似乎cmp_ok在比较的两个部分都需要标量:

not ok 1 - testing method abc
#   Failed test 'testing method abc'
#   at abc.t line 53.
#     'stable_value'
#         ~~
#     '2'

“预期”插槽中的数组在标量上下文中计算并转换为2。

我可以通过使用like的hack并对数组进行字符串化来解决这个问题,但是使用smartmatch运算符作为比较方法(如when)进行测试会很好。有没有办法用Test :: More或其他模块做到这一点?

目前我正在使用:

ok($known_value ~~ @returned, 'testing method abc')
  or diag (
      "ERROR:\n".
      "Found: ". Dumper @returned."\n".
      "Expected at least one element equal to '$known_value'"
  )

这是我能做的最好的吗?

3 个答案:

答案 0 :(得分:9)

由于Perl如何将参数传递给子例程,因此无法使用@returned。 (数组被展平到参数列表中并失去其身份。)改为传递数组引用:

cmp_ok($known_value, '~~', \@returned, 'testing method abc')

智能匹配运营商足够聪明,可以做正确的事情。来自perlsyn:

  

请注意智能匹配隐式   取消引用任何非祝福的哈希或   数组引用,所以“哈希”和“数组”   条目适用于这些情况。

答案 1 :(得分:3)

Test::Deep提供了许多实用程序来测试(可能非常嵌套的)结构的部分,并且在出现故障时也会产生非常有用的诊断。我相信其bag函数之一可以为你完成这项工作。

use Test::Deep;

my @foo = ('bar', 'baz', 'moo');

cmp_deeply(
    \@foo,
    superbagof('baz'),
    '@foo contains at least one "baz"',
);

通过这种方式,如果事实证明是必要的,你可以做出比智能匹配允许的更复杂的断言,而不必将事情分解成更小的块,并且还将继续在旧的perls上运行。

答案 2 :(得分:2)

使用Test::MoreTest::Most自动转储:

use Test::More 0.82; diag explain \@returned;

use Test::Most 0.21; show \@returned;