Как «поймать» выход pod2usage в Perl Script с помощью Try :: Tiny? - PullRequest
1 голос
/ 01 августа 2011

Я сейчас пытаюсь научиться юнит-тестированию. Для этого я пишу скрипт на работе и создаю модульные тесты для всего скрипта. Пока что дела идут хорошо, но я пытаюсь проверить, что неверные данные, введенные в сценарий из командной строки, вызывают сообщение справки.

Мой код выглядит примерно так:

sub getContext{
   my ($help) = @_;

GetOptions(
  help|h => \$help,
   ...

pod2usage if $help;
... 
}

Мои тесты выглядят примерно так:

my $help_exception = 0;
try{  
   getContext( {help => 0} );
}catch{
 $help_exception = 1; 
}

ok($help_exception, "Script died correctly when given help flag");

Мой вывод выглядит очень похоже на:

1..4

ok 1 - use scripts::scriptname;

ok 2

ok 3

# Looks like you planned 4 tests but ran 3.

# Looks like your test exited with 1 just after 3.

Тест для флага справки - это тест 4, похоже, что мой скрипт завершает работу, не вызывая блок Try :: Tiny try catch. Есть ли способ исправить это, или я должен писать свои тесты по-другому?

Ответы [ 3 ]

4 голосов
/ 01 августа 2011
Документация

Pod::Usage для аргумента -exitval показывает, как не допустить выхода из нее все вместе.Вы можете просто использовать это и соответствующим образом адаптировать свой код и / или тесты.

В противном случае exit не является исключением и, следовательно, не может быть перехвачено как исключение.Тем не менее, он может быть переопределен через CORE::GLOBAL::exit.Использование этого также является разумным подходом, при условии, что вы правильно локализуете свои модификации.

В качестве альтернативы, вы всегда можете просто запустить подпроцесс, чтобы запустить весь сценарий и записать, что он делает, основываясь на своих тестах, полностью избегаяпроблема Pod::Usage вызова exit.

В соответствующей заметке то, как вы используете Try::Tiny в своем тесте, немного странно.Я полагаю, что использование Test::Fatal (основанное на Try::Tiny) может помочь в более четких тестах в будущем.

2 голосов
/ 01 августа 2011

Проблема в том, что pod2usage делает exit и не выдает исключение. Я не думаю, что это может быть захвачено таким образом.

Почему бы не вызвать весь сценарий в тесте и проверить возвращаемое значение / вывод, соответствующий вашим ожиданиям?

1 голос
/ 01 августа 2011

Как bvr ответил: программа / скрипт на самом деле не тестируется на модули, так как он не состоит из повторно используемых частей / блоков. Вы должны проверить это целостно. Выполните его с аргументами командной строки и проверьте его вывод и ошибки. Например, используя Capture :: Tiny & ndash;

use warnings;
use strict;
use Capture::Tiny qw( capture );
use Test::More;

my $script = "/bin/ls";

plan skip_all => "Have no `$script` to check"
    unless -x $script;

my ( $out, $err ) = capture {
    system($script, "-1", "/");
};

like( $out, qr{^bin$}m, "$script finds bin" );
ok( ! $err, "...without error" );

done_testing(2);

Вывод из prove & ndash;

/home/apv/ab ..
ok 1 - /bin/ls finds bin
ok 2 - ...without error
1..2
ok
All tests successful.
...