Your SlideShare is downloading. ×
  • Like
Опыт разработки и тестирования RESTful JSON сервиса
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Опыт разработки и тестирования RESTful JSON сервиса

  • 1,006 views
Published

Кое-что о процессах и технологиях, которые используются при разработке системы, основой которой является RESTful JSON API.

Кое-что о процессах и технологиях, которые используются при разработке системы, основой которой является RESTful JSON API.

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,006
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
5
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Опыт разработки и тестирования RESTful JSON сервиса
  • 2. Требования к системе● Удобство для реселлеров● Возможность брендирования● Гибкость и возможность расширения за счет подключаемых модулей
  • 3. Реализация CustomerF Login BR AO API CN Domain KT EEND N D ... VPS
  • 4. RESTful API● Ресурсы (объекты)● URI – идентификатор ресурса● HTTP методы (POST, GET, PUT, PATCH, DELETE)● Формат передачи данных на выбор (HTML, XML, JSON, …)● Метаданные
  • 5. REST + Dancerpost /email/:domain => sub { … };get /email/:domain => sub { … };get /email/:domain/:mailbox => sub { … };put /email/:domain/:mailbox => sub { … };patch /email/:domain/:mailbox => sub { … };del /email/:domain/:mailbox => sub { … };
  • 6. Dancerdancer/ ... +-- config.yml +-- dancer.pl +-- domain/ +-- customer/ | +-- lib/ | +-- lib/ | | +-- domain.pm | | +-- customer.pm | +-- t/ | +-- t/ +-- cpanel/ +-- login/ | +-- lib/ | +-- lib/ | | +-- cpanel.pm | | +-- login.pm | +-- t/ | +-- t/ +-- vps/ +-- lib/ ... | +-- vps.pm +-- t/
  • 7. Routesget /domain => sub : Auth( Admin Marketing Reseller){ Chimera::API::Domain->get(params());};
  • 8. Routes - Authenticationuse base qw(Dancer::Chimera::App);use Dancer qw(:syntax);get /domain => sub : Auth( Admin Marketing Reseller){ Chimera::API::Domain->get(params());};Dancer::Plugin::Auth::Extensible
  • 9. Routes - Controllersget /domain => sub : Auth( Admin Marketing Reseller){ Chimera::API::Domain->get(params());};
  • 10. ControllersChimera/API/ +-- Basket.pm +-- Basket/ | +-- Item.pm +-- Cpanel.pm +-- Cpanel/ | +-- Addondomain.pm | +-- SSL.pm +-- Customer.pm +-- Customer/ | +-- Service/ | +-- Service.pm | +-- User/ | +-- User.pm +-- Domain.pm ... +-- Utils.pm
  • 11. Server-side programsuse Dancer::Chimera qw(catch_output);my %domain_data = catch_output( Chimera::API::Domain, create, %param);return $domain_data{output} if $domain_data{error};# Process output…;
  • 12. Тестирование<sam> Doing the tests afterwards is like puttinga condom on after youve come.
  • 13. Test-driven development● Добавить тест● Запустить тесты: убедиться, что новые тесты не проходят● Написать код● Запустить тесты: убедиться, что все тесты проходят● Рефакторинг● Повторить
  • 14. Тестирование APIuse Test::ChimeraAPI;Test::ChimeraAPI::run_tests( { title => Create: normal mailbox, call => [ POST => /email => %mailbox_details, ], expect => { http_code => HTTP_CREATED, data => { success => 1 }, }, },);
  • 15. Тестирование APIt/ (master) $ prove -v api.t1..78ok 1 - Create: normal mailbox: HTTP codeok 2 - Create: normal mailbox data is hashref as expectedok 3 - Create: normal mailbox{success} data: scalar as expectedok 4 - Create: normal mailbox{success} data: is 1ok 5 - Create: normal mailbox data all matches...
  • 16. Тестирование1.Написать тест и код2.Запустить тесты3.Увидеть кучу непонятных ошибок...4.Понять, что сервер не перезапустился...5.Исправить ошибки6.Вернуться к пункту 2
  • 17. Тестирование1.Написать тест и код2.Запустить тесты3.Увидеть кучу непонятных ошибок...4.Понять, что сервер не перезапустился...5.Исправить ошибки6.Вернуться к пункту 2
  • 18. Dancer::Test● Test::ChimeraAPI::request() – request_remote() - if $ENV{CHIMERA_SERVER} ● LWP::UserAgent::request() – request_internal() ● Dancer::Test::dancer_response()
  • 19. Dancer::Test - плюсы● Не нужно запускать сервер: – Держать открытую вкладку – Ждать рестарта – Получать ошибки соединения – Не отвлекаешься от процесса кодирования● Загружаются только нужные приложения
  • 20. Dancer::Test - минусы● Условия менее близки к реальным● Загрузка приложений при каждом запуске теста → общее время тестирования выше
  • 21. Test::Class● Фреймворк для представления тестов в виде классов● Удобно для тестирования ОО-кода● При работе с большим количеством тестовCurtis (Ovid) Poehttp://www.modernperlbooks.com/mt/2009/03/organizing-test-suites-with-testclass.htmlhttp://www.slideshare.net/Ovid/testing-with-testclass
  • 22. Test::Class - плюсы● Однократная загрузка Dancer-приложений – Может пригодиться для любых “тяжёлых” модулей● Много других “плюшек” – Фазы подготовки / очистки – Наследование – Тестирование отдельных классов через prove – Тестирование отдельных методов – и т.д.
  • 23. Test::Class - минусы● Требует изучения (в том числе и исходников)● Нужна реорганизация тестов
  • 24. Test::Class - тестыt/ +-- class.t +-- lib/ +-- Email/ +-- Test/ +-- Create.pm +-- Delete.pm +-- Get.pm +-- Patch.pm +-- Put.pm +-- Rename.pm +-- API.pm
  • 25. class.t#!/usr/bin/env perluse lib::abs ../../../lib;use our::way;use Test::Class::Load lib::abs::path(lib);
  • 26. Удалённые системы Тесты API-серверdomains cpanel vps Сторонние APIRegistrar cPanel API VPS API API
  • 27. Удалённые системы● Взаимодействие по сети – Медленно – Необходимо подключение к Интернет – Поддержка тестовых серверов● Тормоза самих систем – Создание VPS занимает ~1 мин● Конфликты при одновременном запуске тестов
  • 28. Mock-тестирование● Пишем тесты и код● Доводим до рабочего состояния с использованием реальной удалённой системы● Записываем ответы сервера● Подменяем записанными ответами реальные
  • 29. Mock-тестирование - протоколы● HTTP (LWP::UserAgent) – большая часть систем● Другие
  • 30. Test::LWP::Recorder● Запись ответов сервера в файлы $request_md5sum● Подстановка записанных ответов
  • 31. Test::LWP::RecorderGET http://foreign.api/something/:id - $resp1PATCH http://foreign.api/something/:id - $resp2GET http://foreign.api/something/:id - $resp1 (адолжен быть $resp3)
  • 32. Test::LWP::UserAgent● Inspired by Test::Mock::LWP::Dispatch by Yury Zavarin● Активно (более-менее) разрабатывается● Расширяет возможности LWP::UserAgent● Содержит интересные и полезные фичи http://www.perladvent.org/2012/2012-12-12.html
  • 33. Test::LWP::UserAgent – register_psgi$useragent->register_psgi($hostname, $app);Используется любой PSGI-совместимыйфреймворк.Например, Dancer :)
  • 34. Но... ТестыПроцесс API-сервер domains cpanel vps Сторонние API Registrar cPanel API VPS API API
  • 35. Но... ТестыПроцесс API-сервер API-сервер domains cpanel vps Сторонние API Registrar cPanel API VPS API API
  • 36. В Dancer всё глобально!● Конфигурация (settings в Dancer::Config) – Serializer● Хуки (singleton Dancer::Factory::Hook->hooks) – Аутентификация● Переменные (vars в Dancer::SharedData) – Используются внутри нашего API, не определены в mocked API
  • 37. Инжекция mock-данных● Test::ChimeraAPI::Mocking – Подготовка mocked классов в секции startup() – Глобальная переменная $Mock::Something::API● Mock-данные инжектированы в сам тестовый класс● Mock-класс проверяет наличие данных и возвращает их в порядке timestamp или отправляет запрос к серверу● Запись в файл при необходимости
  • 38. Юнит-тестированиеЮнит-тестирование – это тестированиекаждого неделимого блокафункциональности в изоляции – не тольковозвращаемых значений для различныхаргументов, но также взаимодействия этихблоков с другими частями приложенияпутём имитации работы этих частей. http://tinyurl.com/c4rweaw
  • 39. Mocking в юнит-тестахpackage Provisioner;use Provisioner::Mapper;my $provisioner_mapper;__PACKAGE__->reset_provisioner_mapper;sub reset_provisioner_mapper { shift->provisioner_mapper(Provisioner::Mapper);}sub provisioner_mapper { if ($_[1]) { $provisioner_mapper = $_[1] }; return $provisioner_mapper;}sub create { my ($self, $serviceplan) = @_; my $class = $self->provisioner_mapper($serviceplan->codename); return $class->new;}
  • 40. Mocking в юнит-тестахsub provision_regrade_check_sp_is_passed_to_provisioner :Tests { my $self = shift; Provisioner->provisioner_mapper(Chimera::UnitTest::Mock::Generic->new([ { method => mapping, input => [cpanel_shared_hosting], output => Chimera::UnitTest::Mock::Provisioner::CheckRegradeMethodCall }, ])); my($order, $action) = $self->_place_order($self->basket()); my $processed = Chimera::API::Action->process($action); Provisioner->reset_provisioner_mapper();}
  • 41. Devel::Cover● Оценка покрытия тестами● $^P ($PERLDB) == 0x104; – Выключена оптимизация● Не работают атрибуты :(
  • 42. Devel::Coverpackage Dancer::Chimera::App;use attributes;my %attrs;sub MODIFY_CODE_ATTRIBUTES { my ($package, $subref, @attrs) = @_; $attrs{ refaddr $subref } = @attrs; return;}…my $subref = sub : Auth(MyRole) { … };…http://tinyurl.com/bptkr9a - багрепорт в perl5.porters
  • 43. Документация проекта● POD● Pod::HTML5::BrowserКод:https://github.com/LoonyPandora/Pod-HTML5-BrowserПрезентация:https://speakerdeck.com/loonypandora/documentation-for-fun-and-profit
  • 44. Спасибо!Илья Чесноков <chesnokov.ilya@gmail.com>
  • 45. Вопросы?