Как я могу перехватить 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")вы получите более полезный результат, но все тесты будут прерваны, а не только текущий тестовый сценарий.

Есть ли разумный способ распечатать диагностическое сообщение, которое будет видно на provestderr и в итоговом выводе, когда жгут выходит, затем перейти к следующему сценарию тестирования?

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;

чтобы быть более точным, вы действительно выходите туда.

Другие вопросы по тегам