ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
модульное тестирование для Perl. алексей шруб. зал 4
1. Unit testing for Perl
Alexey Shrub
Российские интернет-технологии
2011-04-26
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 1/30
2. Модульное тестирование
Автоматизированное.
Изолированное.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 2/30
3. Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
4. Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Борьба с ростом энтропии (регрессом) при изменениях (= легкость
рефакторинга).
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
5. Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Борьба с ростом энтропии (регрессом) при изменениях (= легкость
рефакторинга).
Локализация ошибок (в отличие от интеграционных).
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
6. Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Борьба с ростом энтропии (регрессом) при изменениях (= легкость
рефакторинга).
Локализация ошибок (в отличие от интеграционных).
Раннее обнаружение ошибок (чем раньше, тем дешевле исправление
ошибки).
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
7. Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Борьба с ростом энтропии (регрессом) при изменениях (= легкость
рефакторинга).
Локализация ошибок (в отличие от интеграционных).
Раннее обнаружение ошибок (чем раньше, тем дешевле исправление
ошибки).
Раннее обнаружение неудобного интерфейса.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
8. Зачем нужны модульные тесты
Необходимая верификация (+ двойная запись).
Борьба с ростом энтропии (регрессом) при изменениях (= легкость
рефакторинга).
Локализация ошибок (в отличие от интеграционных).
Раннее обнаружение ошибок (чем раньше, тем дешевле исправление
ошибки).
Раннее обнаружение неудобного интерфейса.
Документация.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 3/30
9. Стандартные отмазки нежелающих писать тесты
Нет времени.
Код нетестируемый.
Не умею и боюсь, у меня и без тестов вроде/должно работать.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 4/30
10. Тесты в Perl. Функциональное тестирование
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 5/30
11. use Test::More;
Базовые функции
ok
is
new_ok
is_deeply
...
Диагностика (diag/explain):
i s _ d e e p l y ( $got , $ e x p e c t e d , ’ R e s u l t must be . . . ’ )
or diag e x p l a i n $got ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 6/30
12. Минимальный пример
Пример положительного функционального теста
#! / u s r / b i n / p e r l −w
use s t r i c t ;
use T e s t : : More t e s t s => 1 ;
use E m a i l : : V a l i d ;
my $ e m a i l = ’ w o r l d . mind@yahoo . com ’ ;
my $ e x p e c t e d = $ e m a i l ;
my $ g o t = E m a i l : : V a l i d −>a d d r e s s ( $ e m a i l ) ;
i s ( $got , $ e x p e c t e d , " $ e m a i l must be v a l i d " ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 7/30
13. Запуск одного теста
TAP - Test Anything Protocol
Run test
$ perl t/simple-test.t
1..1
ok 1 - world.mind@yahoo.com must be valid
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 8/30
14. Запуск набора тестов
Run tests with Test:Harness
$ prove
t/simple-test.t .. ok
t/use.t .......... ok
All tests successful.
Files=2, Tests=2, 1 wallclock secs ( 0.02 usr 0.01 sys + 0.14 cusr
Result: PASS
Makefile - бывает удобнее
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 9/30
15. Тестирование исключений
Test::Exception
#! / u s r / b i n / p e r l −w
use s t r i c t ;
use F a t a l qw( open c l o s e ) ;
use T e s t : : More t e s t s => 1 ;
use T e s t : : E x c e p t i o n ;
my $ f i l e n a m e = ’ t h e _ n o t _ e x i s t e d _ f i l e ’ ;
throws_ok { open (my $fh , "<" , $ f i l e n a m e ) }
q r /No s u c h f i l e / ,
’ open ( ) w i t h 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
16. Генерация входных данных
Test::LectroTest::Compat
#! / u s r / b i n / p e r l −w
use s t r i c t ;
use T e s t : : More t e s t s => 1 ;
use T e s t : : L e c t r o T e s t : : Compat ;
my $ p r o p _ n o n n e g a t i v e = P r o p e r t y {
##[ x <− I n t ]##
cmp_ok ( abs ( $x ) , ’>= ’ , 0 ) ;
} , name => " a b s o u t p u t must be non− n e g a t i v e " ;
holds ( $prop_nonnegative ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 11/30
17. Что делать, если модуль взаимодействует с внешним миром?
Пишет/читает базу.
Обращается к web страницам/скриптам.
Пишет/читает memcache.
Вызывает SOAP/XML-RPC сервисы.
и т.п.
?
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 12/30
18. Mock/Stub/Fake
Mock модули общего назначения
Test::MockObject
Test::MockModule
Test::MockClass
Специализированные
DBD::Mock
Test::Mock::LWP
Cache::Memcached::Mock
и т.п.
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 13/30
19. Пример подмены модуля LWP I
#! / u s r / b i n / p e r l −w
use s t r i c t ;
use T e s t : : More t e s t s => 3 ;
use T e s t : : MockObject ;
use Cache : : Memcached : : F a s t ;
use l i b qw( l i b ) ;
my $server = ’ l o c a l h o s t :11211 ’ ;
my $key = ’ mykey ’ ;
my $value = ’ value ’ ;
my $newvalue = ’ newvalue ’ ;
BEGIN {
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 14/30
20. Пример подмены модуля LWP II
$_ = ’ MyMemcacheWrapper ’ ;
use_ok ( $_ ) ;
}
# moking Cache : : Memcached : : F a s t
my $memc_mock = T e s t : : MockObject −>new ( ) ;
T e s t : : MockObject −>fake_module ( ’ Cache : : Memcached : : F a s t ’ ,
new => sub { $memc_mock } ) ;
my $memcache = {
$key , $ v a l u e ,
};
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 15/30
21. Пример подмены модуля LWP III
$memc_mock−>mock (
’ get ’ ,
sub {
my ( $ s e l f , $ ke y ) = @_;
return $memcache −>{$ ke y } ;
}
);
$memc_mock−>mock (
’ set ’ ,
sub {
my ( $ s e l f , $key , $ v a l u e ) = @_;
$memcache −>{$ ke y } = $ v a l u e ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 16/30
22. Пример подмены модуля LWP IV
}
);
# g e t o u r w r a p p e r o b j e c t and memcached c o n n e c t i o n
my $mem_wrap = new_ok ( $_ , [ s e r v e r => $ s e r v e r ] ) ;
my $memcached = new Cache : : Memcached : : F a s t (
{ s e r v e r s => [ { a d d r e s s => $ s e r v e r } , ] , } ) ;
# check s e t
$mem_wrap−>s e t _ v a l u e ( $key , $ n e w v a l u e ) ;
i s ( $memcached−>g e t ( $ key ) , $n e w v a l u e ,
’ s e t _ v a l u e must s e t v a l u e i n memcache ’ ) ;
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 17/30
23. Нефункциональное тестирование
Автоматизированный code review
Почему?
Зачем?
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 18/30
24. Компилируется?
Test::Strict
#! / u s r / b i n / p e r l −w
use s t r i c t ;
use w a r n i n g s ;
use T e s t : : More ;
use T e s t : : 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
25. Соответствует соглашению о стиле кодирования?
Test::EOL
Test::NoTabs
Test::PerlTidy
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 20/30
26. Используются ли рекомендации из Perl Best Practice
Test::Perl::Critic
Test::Portability::Files
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 21/30
27. Не забыли ли чего? (инструменты в больном)
Test::Fixme
Test::NoBreakpoints
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 22/30
28. Метрики в норме?
Perl::Metrics::Simple
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 23/30
29. Есть ли документация?
Test::Pod
Test::Pod::Coverage
Test::Spelling
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 24/30
30. Есть ли нужное количество тестов?
Test::Strict (Devel::Cover)
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 25/30
31. Не стал ли код медленнее?
Test::Timer
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 26/30
32. Нет ли утечек памяти?
Test::Weaken
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 27/30
33. О чём говорит успешное прохождение таких тестов?
Код компилируется! Это уже успех!
Стиль кодирования соответствует заданному!
Выполняются хотя бы минимальные рекомендации из PBP!
Доделано всё, о чем были пометки!
Метрики сложности дают надежду на то, что код можно понять!
Была попытка написать документацию ко всем методам!
Есть тесты! И их количество соответствует запланированному!
Код ещё не самый тормозной!
Можно надеяться на то, что память не течёт!
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 28/30
34. Максимальный набор, все кроме последних двух не зависят от кода, можно
копипастить и запускать
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 29/30
35. Вопросы
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:
ashrub@yandex.ru
Alexey Shrub, Российские интернет-технологии Unit testing for Perl 30/30