[Moscow.pm] Научите писать красивые тесты

Гришаев Анатолий agrishaev на gmail.com
Чт Июн 30 13:25:09 PDT 2016


Если "покурить" подорвет здоровье есть хакерский способ добиться желаемого

////////////////////////////////////////////////////
use Test::Deep;
use Test::More qw(no_plan);

sub test_case{
    my ($a,$b, $c) = @_;
    local $Test::Builder::Level = $Test::Builder::Level + 1;
    cmp_deeply( $a, $b, $c );

}
sub main{
    my @argv  = @_;
    test_case( [1], [2], 'aaa');   #


#   done_testing();
};
///////////////////////////////////////////////////

30 июня 2016 г., 23:11 пользователь Гришаев Анатолий <agrishaev на gmail.com>
написал:

> Почему же, вот пример из документации Test::Deep:
> USING TEST::DEEP WITH TEST::BUILDER [image: ^]
>
> Combining cmp_details and test_diag makes it possible to use Test::Deep
> in your own test classes.
>
> In a Test::Builder <http://search.cpan.org/perldoc?Test%3A%3ABuilder>
> subclass, create a test method in the following form:
>
>   sub behaves_ok {
>     my $self = shift;
>     my $expected = shift;
>     my $test_name = shift;
>
>     my $got = do_the_important_work_here();
>
>     my ($ok, $stack) = cmp_details($got, $expected);
>     unless ($Test->ok($ok, $test_name)) {
>       my $diag = deep_diag($stack);
>       $Test->diag($diag);
>     }
>   }
>
> As the subclass defines a test class, not tests themselves, make sure it
> uses Test::Deep::NoTest
> <http://search.cpan.org/%7Erjbs/Test-Deep-1.120/lib/Test/Deep/NoTest.pm>,
> not Test::Deep itself.
>
>
> Похоже покурить прийдется, но я думаю это не полеты в космос.
>
>
> 30 июня 2016 г., 22:28 пользователь Victor Efimov <victor на vsespb.ru>
> написал:
>
> Круто, буду юзать. Похоже сложные вещи, типа, не is_eq, а cmp_deeply
>> из Test::Deep так заюзать нельзя?
>>
>> 30 июня 2016 г., 21:38 пользователь Гришаев Анатолий
>> <agrishaev на gmail.com> написал:
>> > Когда тест фейлится то печатает номер строки из которой был вызван is()
>> > а если используешь $tb->is_eq, то печатается номер строки где была
>> вызвана
>> > test_case.
>> >
>> > в первом случае это одна строка на все тесты, а во втором на каждый тест
>> > своя строка.
>> >
>> > Помогает, если ты не имеешь доступа к той тачке, где тесты
>> > проходят(cpan-testers например)
>> > В первом случае ты знаешь, что какой-то тест в файле сломался, а во
>> втором
>> > знаешь какой именно тест сломался,
>> > даже если ты не дал для него имя или у двух тестов оно каким-то образом
>> > получилось одинаковым (бывало, такова жизнь).
>> >
>> >
>> >
>> >
>> >
>> >
>> > 30 июня 2016 г., 21:07 пользователь Victor Efimov <victor на vsespb.ru>
>> > написал:
>> >
>> >> а зачем, кстати, $tb ?
>> >>
>> >> 30 июня 2016 г., 20:59 пользователь Гришаев Анатолий
>> >> <agrishaev на gmail.com> написал:
>> >> > Спасибо Акжан и Виктор за ваши варианты.
>> >> >
>> >> > Вообщем использовал обе идеи и добавил, что-то от себя.
>> >> > 1) использовал именованные параметры для ясности
>> >> > 2) Завернул в функцию
>> >> > 3) Используем номера строк для нахождения failing case
>> >> >
>> >> > Получилось в итоге.
>> >> > =========================
>> >> > test_case(
>> >> >    input => "input 1",
>> >> >    output => "result 1",
>> >> > );
>> >> > ...
>> >> > test_case(
>> >> >    input => "input 2",
>> >> >    output => "result 2",
>> >> > );
>> >> >
>> >> > sub test_case{
>> >> >      my $tb = Test::Builder->new;
>> >> >      ...
>> >> >       $tb->is_eq( ... );
>> >> > };
>> >> > =========================
>> >> >
>> >> >
>> >> > 30 июня 2016 г., 20:21 пользователь Гришаев Анатолий
>> >> > <agrishaev на gmail.com>
>> >> > написал:
>> >> >
>> >> >> Не совсем эквивалентно теряется информация о строке в которой
>> определен
>> >> >> тест
>> >> >>
>> >> >> Можно твой вариант улучшить чуть-чуть
>> >> >>
>> >> >> вместо
>> >> >> .............
>> >> >> sub test_case {
>> >> >>   my ($want_result,  $input) = @_;
>> >> >>
>> >> >>   my $r = my_func($input)
>> >> >>   ok($r)
>> >> >>   is($r->string, $want_result, "parse $input")
>> >> >> }
>> >> >> ..........................
>> >> >>
>> >> >> Лучше писать
>> >> >> ////////////////////
>> >> >>
>> >> >> sub test_case {
>> >> >>   my ($want_result,  $input) = @_;
>> >> >> +my $tb = Test::Builder->new;
>> >> >>   my $r = my_func($input)
>> >> >>   $tb->ok($r)
>> >> >>   -is($r->string, $want_result, "parse $input")
>> >> >>   +$tb->is_eq($r->string, $want_result, "parse $input");
>> >> >> }
>> >> >> /////////////////////
>> >> >>
>> >> >> Я от подобного варианта ушел, не смог заставить писать в таком
>> стиле,
>> >> >> из-за собственных требований к красоте.
>> >> >>
>> >> >>
>> >> >>
>> >> >> 30 июня 2016 г., 19:53 пользователь Victor Efimov <victor на vsespb.ru
>> >
>> >> >> написал:
>> >> >>
>> >> >>> или
>> >> >>> я переодически делаю вместо
>> >> >>> ===
>> >> >>> my ($want_result,  $input) = ( "вход 1", "выход 1")
>> >> >>>
>> >> >>> my $r = my_func($input)
>> >> >>> ok($r)
>> >> >>> is($r->string, $want_result, "parse $input")
>> >> >>> ===
>> >> >>>
>> >> >>> так:
>> >> >>>
>> >> >>> ===
>> >> >>> sub test_case {
>> >> >>>   my ($want_result,  $input) = @_;
>> >> >>>
>> >> >>>   my $r = my_func($input)
>> >> >>>   ok($r)
>> >> >>>   is($r->string, $want_result, "parse $input")
>> >> >>> }
>> >> >>>
>> >> >>> test_case( "вход 1", "выход 1");
>> >> >>> test_case( "вход 2", "выход 2");
>> >> >>> test_case( "вход 3", "выход 3");
>> >> >>> test_case( "вход 4", "выход 4");
>> >> >>> ===
>> >> >>>
>> >> >>> что-то в общем-то эквивалентно готовому хэшу с вход-выход
>> >> >>>
>> >> >>> 30 июня 2016 г., 19:46 пользователь Akzhan Abdulin
>> >> >>> <akzhan.abdulin на gmail.com> написал:
>> >> >>> > оно?
>> >> >>> >
>> >> >>> >
>> >> >>> >
>> >> >>> >
>> https://github.com/plack/Plack/blob/master/t/Plack-Middleware/lint_wrong_header_info.t
>> >> >>> >
>> >> >>> > 30 июня 2016 г., 19:25 пользователь Гришаев Анатолий
>> >> >>> > <agrishaev на gmail.com>
>> >> >>> > написал:
>> >> >>> >>
>> >> >>> >> Добрый день Moscow PM!
>> >> >>> >>
>> >> >>> >>
>> >> >>> >> Пишу тесты для сложной функции-монстра
>> >> >>> >>
>> >> >>> >> На вход принимает строку  и на выход "почти" строку.
>> >> >>> >>
>> >> >>> >>
>> >> >>> >> Сейчас тесты выглядят так
>> >> >>> >> ////////////////////////////
>> >> >>> >> my ($want_result,  $input) = ( "вход 1", "выход 1")
>> >> >>> >>
>> >> >>> >> my $r = my_func($input)
>> >> >>> >> ok($r)
>> >> >>> >> is($r->string, $want_result, "parse $input")
>> >> >>> >>
>> >> >>> >> my ($want_result,  $input) = ( "вход 2", "выход 2")
>> >> >>> >>
>> >> >>> >> my $r = my_func($input)
>> >> >>> >> ok($r)
>> >> >>> >> is($r->string, $want_result, "parse $input")
>> >> >>> >> //////////////////////////
>> >> >>> >>
>> >> >>> >> Получается куча повторяющего кода, в котором теряется суть
>> >> >>> >>
>> >> >>> >> Можно ли этого избежать и писать более красиво?
>> >> >>> >>
>> >> >>> >>
>> >> >>> >>
>> >> >>> >>
>> >> >>> >>
>> >> >>> >> --
>> >> >>> >> Moscow.pm mailing list
>> >> >>> >> moscow-pm на pm.org | http://moscow.pm.org
>> >> >>> >>
>> >> >>> >
>> >> >>> >
>> >> >>> > --
>> >> >>> > Moscow.pm mailing list
>> >> >>> > moscow-pm на pm.org | http://moscow.pm.org
>> >> >>> >
>> >> >>> --
>> >> >>> Moscow.pm mailing list
>> >> >>> moscow-pm на pm.org | http://moscow.pm.org
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >> > --
>> >> > Moscow.pm mailing list
>> >> > moscow-pm на pm.org | http://moscow.pm.org
>> >> >
>> >> --
>> >> Moscow.pm mailing list
>> >> moscow-pm на pm.org | http://moscow.pm.org
>> >
>> >
>> >
>> > --
>> > Moscow.pm mailing list
>> > moscow-pm на pm.org | http://moscow.pm.org
>> >
>> --
>> Moscow.pm mailing list
>> moscow-pm на pm.org | http://moscow.pm.org
>>
>
>
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20160630/44785afd/attachment-0001.html>


Подробная информация о списке рассылки Moscow-pm