有没有办法如何从子子测试中抛出异常(又名。die
和Carp
家庭成员)并能够抓住它们(又名。eval
或lives_ok
)在Perl 5.10中的父子测试中?
我想在for循环中运行一组测试,如下所示:
use Test::More;
use Test::Exception;
for (my $i=0; $i<=2; $i++) {
subtest("outer $i" => sub {
lives_ok(sub {
inner();
}, "lives_ok");
done_testing();
});
note("Outer code should continue regardless of exceptions in inner().\n");
}
我调用的inner()测试可以在子测试中死掉,例如:
sub inner {
subtest("inner" => sub {
ok(1, 'ok');
die("EXCEPTION message here");
note("This code should NOT be reached\n");
done_testing();
});
}
当inner
子测试结束时,我希望能够继续进行下一次外部测试。但是,在上面的例子中,外部测试也会死掉,lives_ok
对我的问题没用:
ok 1 - ok
# Child (inner) exited without calling finalize()
not ok 1 - inner
not ok 2 - lives_ok
1..2
# Failed test 'inner'
# Failed test 'lives_ok'
# died: EXCEPTION message here at ...
# Child (outer 0) exited without calling finalize()
not ok 1 - outer 0
# Failed test 'outer 0'
# ---------------
# Can't call finalize() with child (inner) active at Test/Builder.pm line 229.
# ---------------
# Tests were run but no plan was declared and done_testing() was not seen.
在现实生活中inner
实际上会调用许多可能死亡的函数,因此我正在寻找一种只涉及更改outer
循环的解决方案。
如果那是不可能的,我将不得不eval
(又名。lives_ok
)所有内部子测试中可能死亡的每个语句,我怎样才能避免嵌套测试是否{{ 1}}通过与否?
lives_ok
编辑:每个循环可以有100个TAP输出行,所以我确实想使用嵌套的子测试
答案 0 :(得分:1)
在子测试中发生未被捕获的异常(从而导致子测试的coderef过早结束)被Test :: More / Test :: Builder视为错误,因此它会出现恐慌和失败。
在这个特定的例子中,我建议可能不需要嵌套第二级子测试。 inner
可以改写为:
sub inner {
# subtest("inner" => sub {
ok(1, 'ok');
die("EXCEPTION message here");
note("This code should NOT be reached\n");
# done_testing();
# });
}
...然后您的整个测试脚本将运行。 (当然,由于lives_ok
测试,测试失败了。)
答案 1 :(得分:0)
除非有人建议更好的解决方案,否则我将重构一下并使用这种解决方法 - 永远不要直接死在子测试中,并调用所有可能在子测试中使用lives_ok而死的函数。
使用问题中的示例:
sub inner {
subtest("inner" => sub {
ok(1, 'ok');
$err = "EXCEPTION message here";
if (not $err) {
note("This code should NOT be reached\n");
}
done_testing();
});
confess($err) if $err;
}