Как я могу перехватить BAIL_OUT () perl Test::More и продолжить следующий тест?
Perl's Test::More
похоже, не предлагает встроенного способа сказать "откажитесь только от этого тестового сценария и перейдите к следующему".
Вы можете exit()
или die()
но это не дает вам очень полезного вывода TAP или prove
вывод, просто что-то вроде
t/foo.pl (Wstat: 256 Tests: 5 Failed: 0)
Non-zero exit status: 1
Parse errors: Bad plan. You planned 38 tests but ran 5.
что не очень полезно.
если ты BAIL_OUT("reason")
вы получите более полезный результат, но все тесты будут прерваны, а не только текущий тестовый сценарий.
Есть ли разумный способ распечатать диагностическое сообщение, которое будет видно на prove
stderr и в итоговом выводе, когда жгут выходит, затем перейти к следующему сценарию тестирования?
2 ответа
Я пресмыкался в стандартной библиотеке Perl больше, чем когда-либо хотел, чтобы придумать это как мой лучший вариант:
# Install a filter to prevent BAIL_OUT() from aborting the whole
# run.
Test2::API::test2_add_callback_context_init(sub {
my $context = shift;
$context->hub->filter(sub {
my ($hub, $event) = @_;
#
# If you want to see details on the event contents use:
#
#print("EVENT FILTER: " . Dumper($event) . "\n");
# Turn BAIL_OUT() into die(), or maybe $ctx->throw(). We can't easily
# get the context.
if ($event->isa('Test2::Event::Bail')) {
# Ideally we'd produce a Test2::Event with a Test2::EventFacet::Control
# with terminate true, and a Test2::EventFacet::Trace . For for
# now we'll just log the BAIL_OUT() event and exit.
#
# If we ->throw it instead, we get a big stack for little benefit.
# And END { } blocks will still get run when we exit(...) here so
# appropriate cleanup still happens.
#
$event->trace->alert($event->reason);
exit(1);
}
return $event;
});
});
Это вызовет тестовый сценарий, который вызывает BAIL_OUT("FOOBAR");
выручить чем-то вроде
FOOBAR at t/foo.pl line 4.
# Looks like your test exited with 1 just after 5.
тогда prove
stderr покажет:
t/foo.pl ......... 1/38
# Looks like your test exited with 1 just after 5.
и в сводке будет показано
t/foo.pl (Wstat: 256 Tests: 5 Failed: 0)
Non-zero exit status: 1
Parse errors: Bad plan. You planned 38 tests but ran 5.
Это далеко от идеала, так как stderr и сводка не говорят нам, что пошло не так.
Но это мешает BAIL_OUT()
от ядерного удара остальной части пробега.
Одним из недостатков является то, что это не поможет предоставить больше информации для тестов, которые die()
. Так что я все еще ищу варианты получше.
Много раз я просто заворачиваю свои тесты внутрь subtest 'name' => sub { ... }
и использовать return
внутри вроде так:
use Test::More;
subtest 'part 1' => sub {
plan tests => 10;
lives_ok {
...
} "this went smooth"
or return; # no use of further testing
# more tests
fail "I'm done here, bail out!" or return
# more tests
};
done_testing;
Это работает, потому что прохождение тестов возвращает "истина", а неудачные тесты возвращают "ложь" и, таким образом, вторая часть or
оценивается.
Это не сломает TAP, вы можете "выйти из строя" из подтеста или всего теста (если он завернут) и продолжить выполнение остальных тестов.
Мой вариант использования заключается в том, что если я не могу создать экземпляр тестового объекта для дальнейшего тестирования, остальные тесты в этом подтесте будут просто бесполезны, ни один из этих тестов не имеет смысла, и я получаю только загроможденные отчеты о тестах.
Вы потенциально могли бы сделать:
lives_ok {
...
} "Yay"
or fail "No use to continue here, bye!" or return;
чтобы быть более точным, вы действительно выходите туда.