[Kiev-pm] [announce] Assert::Refute - унификация ассертов и юнит-тестов
Konstantin S. Uvarin
khedin at gmail.com
Wed Jan 10 05:40:23 PST 2018
Приветствую!
Вышел и активно развивается модуль Assert::Refute[1], суть такова:
use Assert::Refute qw(:all);
my ($foo, $bar);
# тут куча кода, который сложно протестировать
refute_these {
like $foo, qr/f?o?r?m?a?t/;
isa_ok $bar, "My::Module";
}; # carp, если условия не выполняются
Таким образом, создаётся (1) защита от дурака при изменении кода,
рефакторингах и т.п. и (2) прототип будущего юнит-теста.
Даже если речь не о легаси-коде, проверка инвариантов и разумных границ
может быть полезна:
use Assert::Refute;
use Assert::Refute::T::Numeric qw(is_between);
refute_these {
is_between $price, 0.01, 1000, "Price within bounds";
};
По сути это контрактное программирование [2], только в оцень легковесной
форме.
Что ещё есть:
* refute $reason, "explanation"; - очень мощный базовый метод, по сути это
ok и diag в одном флаконе - если причина не тру, то всё хорошо, а если она
тру, то понятно, что именно не так.
* subcontract "name" => sub { # тут условия }
Аналог subtest, но работает не только в юнит-тестах (в юнит-тестах, таки
да, просто вызов Test::Builder->subtest внутри).
* Assert::Refute::Build - конструирование собственных условий/проверок. В
простейшём случае всё, что нужно - чистая функция, которая возвращает ложь,
если всё хорошо, и _что именно_ пошло не так, если что-то пошло не так (ср.
diff)
Под Test::More тоже будет работать точно так же, если его (или что угодно
на базе Test::Builder, напр. Test::Exception) подключили раньше.
* Assert::Refute::Contract - прототип _настоящего_ контрактного
программирования, пока что наиболее применим для тестирования тестов,
написанных в предыдущем пункте.
* Assert::Refute::Exec - объектно-ориентированный интерфейс, если неохота
поганить неймспейс всякими is и like и вообще хочется более тонкого
контроля.
* Assert::Refute::T::* - немного дополнительный проверок, вроде "массив
отсортирован так-то", "у хеша такие-то ключи" или "число от и до".
А что с производительностью? Как-то так:
bash# perl -MAssert::Refute=:all -we '$SIG{ALRM} = sub { $stop++ }; alarm
1; refute_these { like ++$i, qr/[0-9]/ while !$stop}; print $i';
278022
bash# grep MHz /proc/cpuinfo
cpu MHz : 2400.070
Далее планируется:
* управление тестами - plan, skip, bail_out, TODO
* больше собственно проверок
* полезные дополнения типа работы с временными файлами
Репо и анонс на perlmonks:
https://github.com/dallaylaen/assert-refute-perl
http://perlmonks.org/?node_id=1206533
[1] https://metacpan.org/pod/Assert::Refute
[2] https://metacpan.org/pod/Class::Contract
--
Konstantin S. Uvarin
jabber: see <from>
skype: kuvarin
http://github.com/dallaylaen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/kiev-pm/attachments/20180110/dfc8350b/attachment.html>
More information about the Kiev-pm
mailing list