Test::More - фреймворк для написания тестовых скриптов
Для начала необходимо составить тестовый план. Количество выполняемых тестов в скрипте с помощью:
use Test::More tests => 23;
В случае, если вы заранее не знаете, сколько тестов будет выполнено в скрипте, тогда вы объявляете их в конце файла.
use Test::More;
... ваши тесты ...
done_testing($number_of_tests_run);
Но если тестов очень много или вам лень их считать, то вы можете вообще не указывать $number_of_tests_run
В некоторых случаях вам нужно пропустить весь тестовый файл, так:
use Test::More skip_all => $skip_reason;
Используйте опцию 'import', если вы хотите контролировать какие функции будет экспортировать Test::More
use Test::More tests => 23, import => ['!fail'];
Когда вам нужно вычислить количество тестов, используйте plan() функцию.
use Test::More;
plan tests => keys %Stuff * 3;
Или вообще планировать запуск тестов, так:
use Test::More;
if( $^O eq 'MacOS' ) {
plan skip_all => 'Test irrelevant on MacOS';
}
else {
plan tests => 42;
}
done_testing();
done_testing($number_of_tests);
$number_of_tests - тоже самое, что plan()
Каждому тесту присваивается порядковый номер. Но еще полезно присваивать название каждому тесту.
Основная цель модуля - узнать, прошел тест на OK или not OK.
Методы
ok
ok($got eq $expected, $test_name);
Проверяем любое действие на успешность выполнения.
is
isnt
Сравнивает 1й аргумент со 2м. is - если равны, то ок, а isnt - если НЕ равны то ок.
# Is the ultimate answer 42?
is( ultimate_answer(), 42, "Meaning of Life" );
# $foo isn't empty
isnt( $foo, '', "Got some foo" );
like
like($got, qr/expected/, $test_name);
Проверяет на соответствие регулярному выражению.
unlike
unlike($got, qr/expected/, $test_name);
Проверяет на НЕсоответствие регулярному выражению.
cmp_ok
cmp_ok($got, $op, $expected, $test_name);
Вместо $op - можно использовать любую бинарную операцию (+, &&, и т.д)
can_ok
can_ok($module, @methods);
can_ok($object, @methods);
Проверяет, что модуль или объект может выполнить @methods.
isa_ok
isa_ok($object, $class, $object_name);
isa_ok($subclass, $class, $object_name);
isa_ok($ref, $type, $ref_name);
Проверяет, что объект является экземпляром класса.
new_ok
my $obj = new_ok( $class );
my $obj = new_ok( $class => \@args );
my $obj = new_ok( $class => \@args, $object_name );
Комбинирует создание объекта и вызова isa_ok() на этом объекте.
subtest
subtest $name => \&code;
use Test::More tests => 3;
pass("First test");
subtest 'An example subtest' => sub {
plan tests => 2;
pass("This is a subtest");
pass("So is this");
};
pass("Third test");
Вызывает подтест, со своим планом тестов, в главном скрипте подтест рассматривается, как один тест.
pass
fail
pass($test_name);
fail($test_name);
Просто говорят, что тест прошел на ok или на not ok.
Модульные тесты
use_ok
BEGIN { use_ok($module); }
BEGIN { use_ok($module, @imports); }
обычно используется в блоке BEGIN, чтобы быть уверенным, что модуль загружен удачно.
require_ok
require_ok($module);
require_ok($file);
Подобно use_ok(), но не загружает, а проверяет на доступность.
Смешанные структуры данных
is_deeply
is_deeply( $got, $expected, $test_name );
Подобно is(), но проверяет на равенство структуры данных, сравнивая данные на вложенных уровнях(подуровнях).
Для более точного сравнения используйте модули Test::Differences и Test::Deep.Диагностика
diag
diag(@diagnostic_message);
ok( grep(/foo/, @users), "There's a foo user" ) or
diag("Since there's no foo, check that /etc/bar is set up right");
Выводит диагностическое сообщение, в случае неудачного выполнения теста.
note
note(@diagnostic_message);
Просто заметка, которую хорошо использовать в отладке.
explain
my @dump = explain @diagnostic_message;
is_deeply($have, $want) || diag explain $have;
Используется для представления данных diag и note, в удобный для чтения вид.
Тесты в TODO блоке ожидаются, что будут не выполнены.
BAIL_OUT
Условные тесты
SKIP: BLOCK
SKIP: {
skip $why, $how_many if $condition;
...normal testing code goes here...
}
Пропускаем блок тестов, при определенных условиях.
SKIP: {
eval { require HTML::Lint };
skip "HTML::Lint not installed", 2 if $@;
my $lint = new HTML::Lint;
isa_ok( $lint, "HTML::Lint" );
$lint->parse( $html );
is( $lint->errors, 0, "No errors found in HTML" );
}
TODO: BLOCK
TODO: {
local $TODO = $why if $condition;
...normal testing code goes here...
}
Тесты в TODO блоке ожидаются, что будут не выполнены.
todo_skip
TODO: {
todo_skip $why, $how_many if $condition;
...normal testing code...
Пропускает тесты, помеченные, как TODO.
Контроль тестов
BAIL_OUT
BAIL_OUT($reason);
Прекращает выполнение тестов, если критическая часть программы недоступна (например соединение с БД)
Для лучшего контроля используйте Test::Most
builder
my $test_builder = Test::More->builder;
Для расширения возможностей Test::More когда получаем объект Test::Builder, который использует Test::More.
Коды выхода
0 - все тесты прошли успешно
255 - все не успешно
любое число - количество неудачных тестов (включая те, которые не запланированы)
Примечание: если у вас неудачно выполнилось больше чем 254 тестов, все равно будет выведено 254.
Заметки и предостережения
Использование utf-8
my $builder = Test::More->builder;
binmode $builder->output, ":utf8";
binmode $builder->failure_output, ":utf8";
binmode $builder->todo_output, ":utf8";
Использование потоков
use threads;
use Test::More;
# желательно именно в таком порядке