Upload
rit2011
View
1.195
Download
1
Embed Size (px)
Citation preview
Unit testing for Perl
Alexey Shrub
Российские интернет-технологии
2011-04-26
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 1/30
Модульное тестирование
Автоматизированное.Изолированное.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 2/30
Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).
Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).
Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).
Раннее обнаружение неудобного интерфейса.Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.
Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
Стандартные отмазки нежелающих писать тесты
Нет времени.Код нетестируемый.Не умею и боюсь, у меня и без тестов вроде/должно работать.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 4/30
Тесты в Perl. Функциональное тестирование
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 5/30
use Test::More;
Базовые функцииokisnew_okis_deeply...
Диагностика (diag/explain):
i s_deep l y ( $got , $expected , ’ R e s u l t ␣must␣be␣ . . . ’ )o r d i ag e x p l a i n $got ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 6/30
Минимальный пример
Пример положительного функционального теста
#!/ u s r / b i n / p e r l −wuse s t r i c t ;use Test : : More t e s t s => 1 ;use Emai l : : V a l i d ;
my $ema i l = ’ wor ld . mind@yahoo . com ’ ;my $expec ted = $ema i l ;my $got = Emai l : : Va l i d−>add r e s s ( $ema i l ) ;
i s ( $got , $expected , " $ema i l ␣must␣be␣ v a l i d " ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 7/30
Запуск одного теста
TAP - Test Anything Protocol
Run test
$ perl t/simple-test.t1..1ok 1 - [email protected] must be valid
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 8/30
Запуск набора тестов
Run tests with Test:Harness
$ provet/simple-test.t .. okt/use.t .......... okAll tests successful.Files=2, Tests=2, 1 wallclock secs ( 0.02 usr 0.01 sys + 0.14 cusr 0.02 csys = 0.19 CPU)Result: PASS
Makefile - бывает удобнее
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 9/30
Тестирование исключений
Test::Exception
#!/ u s r / b i n / p e r l −wuse s t r i c t ;use Fa t a l qw(open close ) ;use Test : : More t e s t s => 1 ;use Test : : Excep t i on ;
my $ f i l e n ame = ’ th e_no t_ex i s t e d_ f i l e ’ ;
throws_ok { open (my $fh , "<" , $ f i l e n ame ) }qr /No such f i l e / ,’ open ( ) ␣ w i th ␣bad␣ f i l e ␣name␣must␣ throw␣ e x c e p t i o n ’ ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 10/30
Генерация входных данныхTest::LectroTest::Compat
#!/ u s r / b i n / p e r l −w
use s t r i c t ;use Test : : More t e s t s => 1 ;use Test : : L e c t r oTe s t : : Compat ;
my $prop_nonnegat ive = Prope r t y {##[ x <− I n t ]##cmp_ok( abs ( $x ) , ’>=’ , 0 ) ;
} , name => "abs ␣ output ␣must␣be␣non−n e g a t i v e " ;
h o l d s ( $prop_nonnegat ive ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 11/30
Что делать, если модуль взаимодействует с внешним миром?
Пишет/читает базу.Обращается к web страницам/скриптам.Пишет/читает memcache.Вызывает SOAP/XML-RPC сервисы.и т.п.
?
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 12/30
Mock/Stub/Fake
Mock модули общего назначенияTest::MockObjectTest::MockModuleTest::MockClass
СпециализированныеDBD::MockTest::Mock::LWPCache::Memcached::Mockи т.п.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 13/30
Пример подмены модуля LWP I
#!/ u s r / b i n / p e r l −wuse s t r i c t ;use Test : : More t e s t s => 3 ;use Test : : MockObject ;use Cache : : Memcached : : Fas t ;use l i b qw( l i b ) ;
my $ s e r v e r = ’ l o c a l h o s t :11211 ’ ;my $key = ’mykey ’ ;my $va l u e = ’ v a l u e ’ ;my $newva lue = ’ newva lue ’ ;
BEGIN {
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 14/30
Пример подмены модуля LWP II$_ = ’MyMemcacheWrapper ’ ;use_ok ( $_ ) ;
}
# moking Cache : : Memcached : : Fas tmy $memc_mock = Test : : MockObject−>new ( ) ;Test : : MockObject−>fake_module ( ’ Cache : : Memcached : : Fas t ’ ,
new => sub { $memc_mock } ) ;
my $memcache = {$key , $va lue ,
} ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 15/30
Пример подмены модуля LWP III$memc_mock−>mock (
’ ge t ’ ,sub {
my ( $ s e l f , $key ) = @_;return $memcache−>{$key } ;
}) ;
$memc_mock−>mock (’ s e t ’ ,sub {
my ( $ s e l f , $key , $ v a l u e ) = @_;$memcache−>{$key } = $va l u e ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 16/30
Пример подмены модуля LWP IV}
) ;
# get our wrapper o b j e c t and memcached conne c t i o nmy $mem_wrap = new_ok( $_, [ s e r v e r => $ s e r v e r ] ) ;my $memcached = new Cache : : Memcached : : Fas t (
{ s e r v e r s => [ { add r e s s => $ s e r v e r } , ] , } ) ;
# check s e t$mem_wrap−>set_va lue ( $key , $newva lue ) ;i s ( $memcached−>get ( $key ) , $newvalue ,
’ s e t_va lue ␣must␣ s e t ␣ v a l u e ␣ i n ␣memcache ’ ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 17/30
Нефункциональное тестированиеАвтоматизированный code review
Почему?Зачем?
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 18/30
Компилируется?
Test::Strict
#!/ u s r / b i n / p e r l −wuse s t r i c t ;use warn ing s ;use Test : : More ;use Test : : S t r i c t ;
a l l_p e r l_ f i l e s_o k ( qw/ l i b t x t / ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 19/30
Соответствует соглашению о стиле кодирования?
Test::EOLTest::NoTabsTest::PerlTidy
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 20/30
Используются ли рекомендации из Perl Best Practice
Test::Perl::CriticTest::Portability::Files
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 21/30
Не забыли ли чего? (инструменты в больном)
Test::FixmeTest::NoBreakpoints
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 22/30
Метрики в норме?
Perl::Metrics::Simple
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 23/30
Есть ли документация?
Test::PodTest::Pod::CoverageTest::Spelling
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 24/30
Есть ли нужное количество тестов?
Test::Strict (Devel::Cover)
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 25/30
Не стал ли код медленнее?
Test::Timer
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 26/30
Нет ли утечек памяти?
Test::Weaken
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 27/30
О чём говорит успешное прохождение таких тестов?
Код компилируется! Это уже успех!Стиль кодирования соответствует заданному!Выполняются хотя бы минимальные рекомендации из PBP!Доделано всё, о чем были пометки!Метрики сложности дают надежду на то, что код можно понять!Была попытка написать документацию ко всем методам!Есть тесты! И их количество соответствует запланированному!Код ещё не самый тормозной!Можно надеяться на то, что память не течёт!
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 28/30
Максимальный набор, все кроме последних двух не зависят от кода, можнокопипастить и запускать
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 29/30
Вопросы
QUESTIONS?
Исходники презентации (LaTeX, Beamer):https://github.com/worldmind/perl-unit-testing-presentation-ru.git
Набор тестов:https://github.com/worldmind/perl-test-code-quality-template.git
Feedback to:[email protected]
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 30/30