使用Test :: More和Test :: Deep打印失败的子测试

时间:2013-01-12 13:34:44

标签: perl testing

我使用Test::MoreTest::Deep编写了一个大型测试。 该测试包含子测试。 当我运行代码时,在最后一行我得到:

# Looks like you failed 3 tests of 25.

如何打印指定失败的子测试的摘要? (每个子测试都有一个标题。)

1 个答案:

答案 0 :(得分:6)

简短回答:你不能。

答案稍长:你必须修补Test::BuilderTAP::Harness

Hacky回答:在subtest函数周围放置一个包装器,它捕获名称和结果(subtest(),就像所有测试函数一样,传递时返回true,失败时返回false)并在END块中输出额外的摘要信息。实施留给读者。

tl; dr信息......

Test::Builder(因此整个测试生态系统)不报告摘要中的子测试。我不相信Test :: Builder的发布版本(0.9x)完全存储子测试的结果。子测试在Test :: Builder 0.9x中是一种可怕的黑客攻击。 Test :: Builder 1.5可以更加优雅地处理子测试,所以如果你想制作一个补丁我会用1.5来做。

TAP::Harness(并因此证明)不了解子测试,只要它关注它的垃圾被忽略。为了解决这个问题,每个子测试都会在最后产生一个额外的测试,这是Test :: Harness所理解的。

# TAP::Harness sees this line, the overall plan.
1..1
    # All this indented subtest info is ignored by TAP::Harness.
    ok 1
    ok 2
    not ok 3
    1..3
    # Looks like you failed 1 test of 3.
# TAP::Harness sees this line, and that all it knows about the subtest
# It doesn't even know its a subtest.
not ok 1 - foo

TAP::Harness需要修补以了解子测试,这非常受欢迎。

使用Test::More's own subtest function作为指南的子测试包装器将如下所示:

use Test::Builder;

my @Failed_Subtests;
sub my_subtest {
    my $name = shift;

    # Call subtest
    my $tb = Test::Builder->new;
    my $subtest_ok = $tb->subtest($name, @_);

    # Record the name of any failing subtests
    push @Failed_Subtests, $name if !$subtest_ok;

    return $subtest_ok;
}

# When the test is over, show the failed subtests
END {
    if( @Failed_Subtests ) {
        diag sprintf "These subtests failed: %s", join(", ", @Failed_Subtests);
    }
}

如果你使用my_subtest代替subtest,你会得到类似的内容:

# These subtests failed: bar, baz
# Looks like you failed 2 tests of 3.

您可以替换Test :: More,而不是定义新的子测试功能。函数体看起来相同,但替换Perl函数的技术是另一个问题的主题。