35
Unit testing for Perl Alexey Shrub Российские интернет-технологии 2011-04-26 Alexey Shrub, Российские интернет-технологии Unit testing for Perl 1/30

модульное тестирование для Perl. алексей шруб. зал 4

  • Upload
    rit2011

  • View
    1.198

  • Download
    1

Embed Size (px)

Citation preview

Page 1: модульное тестирование для Perl. алексей шруб. зал 4

Unit testing for Perl

Alexey Shrub

Российские интернет-технологии

2011-04-26

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 1/30

Page 2: модульное тестирование для Perl. алексей шруб. зал 4

Модульное тестирование

Автоматизированное.Изолированное.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 2/30

Page 3: модульное тестирование для Perl. алексей шруб. зал 4

Зачем нужны модульные тесты

Необходимая верификация (+ двойная запись).

Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30

Page 4: модульное тестирование для Perl. алексей шруб. зал 4

Зачем нужны модульные тесты

Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).

Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30

Page 5: модульное тестирование для Perl. алексей шруб. зал 4

Зачем нужны модульные тесты

Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).

Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30

Page 6: модульное тестирование для Perl. алексей шруб. зал 4

Зачем нужны модульные тесты

Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).

Раннее обнаружение неудобного интерфейса.Документация.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30

Page 7: модульное тестирование для Perl. алексей шруб. зал 4

Зачем нужны модульные тесты

Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.

Документация.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30

Page 8: модульное тестирование для Perl. алексей шруб. зал 4

Зачем нужны модульные тесты

Необходимая верификация (+ двойная запись).Борьба с ростом энтропии (регрессом) при изменениях (= легкостьрефакторинга).Локализация ошибок (в отличие от интеграционных).Раннее обнаружение ошибок (чем раньше, тем дешевле исправлениеошибки).Раннее обнаружение неудобного интерфейса.Документация.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30

Page 9: модульное тестирование для Perl. алексей шруб. зал 4

Стандартные отмазки нежелающих писать тесты

Нет времени.Код нетестируемый.Не умею и боюсь, у меня и без тестов вроде/должно работать.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 4/30

Page 10: модульное тестирование для Perl. алексей шруб. зал 4

Тесты в Perl. Функциональное тестирование

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 5/30

Page 11: модульное тестирование для Perl. алексей шруб. зал 4

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

Page 12: модульное тестирование для Perl. алексей шруб. зал 4

Минимальный пример

Пример положительного функционального теста

#!/ 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

Page 13: модульное тестирование для Perl. алексей шруб. зал 4

Запуск одного теста

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

Page 14: модульное тестирование для Perl. алексей шруб. зал 4

Запуск набора тестов

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

Page 15: модульное тестирование для Perl. алексей шруб. зал 4

Тестирование исключений

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

Page 16: модульное тестирование для Perl. алексей шруб. зал 4

Генерация входных данных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

Page 17: модульное тестирование для Perl. алексей шруб. зал 4

Что делать, если модуль взаимодействует с внешним миром?

Пишет/читает базу.Обращается к web страницам/скриптам.Пишет/читает memcache.Вызывает SOAP/XML-RPC сервисы.и т.п.

?

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 12/30

Page 18: модульное тестирование для Perl. алексей шруб. зал 4

Mock/Stub/Fake

Mock модули общего назначенияTest::MockObjectTest::MockModuleTest::MockClass

СпециализированныеDBD::MockTest::Mock::LWPCache::Memcached::Mockи т.п.

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 13/30

Page 19: модульное тестирование для Perl. алексей шруб. зал 4

Пример подмены модуля 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

Page 20: модульное тестирование для Perl. алексей шруб. зал 4

Пример подмены модуля 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

Page 21: модульное тестирование для Perl. алексей шруб. зал 4

Пример подмены модуля 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

Page 22: модульное тестирование для Perl. алексей шруб. зал 4

Пример подмены модуля 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

Page 23: модульное тестирование для Perl. алексей шруб. зал 4

Нефункциональное тестированиеАвтоматизированный code review

Почему?Зачем?

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 18/30

Page 24: модульное тестирование для Perl. алексей шруб. зал 4

Компилируется?

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

Page 25: модульное тестирование для Perl. алексей шруб. зал 4

Соответствует соглашению о стиле кодирования?

Test::EOLTest::NoTabsTest::PerlTidy

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 20/30

Page 26: модульное тестирование для Perl. алексей шруб. зал 4

Используются ли рекомендации из Perl Best Practice

Test::Perl::CriticTest::Portability::Files

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 21/30

Page 27: модульное тестирование для Perl. алексей шруб. зал 4

Не забыли ли чего? (инструменты в больном)

Test::FixmeTest::NoBreakpoints

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 22/30

Page 28: модульное тестирование для Perl. алексей шруб. зал 4

Метрики в норме?

Perl::Metrics::Simple

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 23/30

Page 29: модульное тестирование для Perl. алексей шруб. зал 4

Есть ли документация?

Test::PodTest::Pod::CoverageTest::Spelling

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 24/30

Page 30: модульное тестирование для Perl. алексей шруб. зал 4

Есть ли нужное количество тестов?

Test::Strict (Devel::Cover)

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 25/30

Page 31: модульное тестирование для Perl. алексей шруб. зал 4

Не стал ли код медленнее?

Test::Timer

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 26/30

Page 32: модульное тестирование для Perl. алексей шруб. зал 4

Нет ли утечек памяти?

Test::Weaken

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 27/30

Page 33: модульное тестирование для Perl. алексей шруб. зал 4

О чём говорит успешное прохождение таких тестов?

Код компилируется! Это уже успех!Стиль кодирования соответствует заданному!Выполняются хотя бы минимальные рекомендации из PBP!Доделано всё, о чем были пометки!Метрики сложности дают надежду на то, что код можно понять!Была попытка написать документацию ко всем методам!Есть тесты! И их количество соответствует запланированному!Код ещё не самый тормозной!Можно надеяться на то, что память не течёт!

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 28/30

Page 34: модульное тестирование для Perl. алексей шруб. зал 4

Максимальный набор, все кроме последних двух не зависят от кода, можнокопипастить и запускать

Alexey Shrub, Российские интернет-технологии Unit testing for Perl 29/30

Page 35: модульное тестирование для Perl. алексей шруб. зал 4

Вопросы

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