SlideShare une entreprise Scribd logo
1  sur  47
Télécharger pour lire hors ligne
Опыт разработки и тестирования RESTful
            JSON сервиса
Требования к системе
●   Удобство для реселлеров
●   Возможность брендирования
●   Гибкость и возможность расширения за
    счет подключаемых модулей
Реализация

                 Customer


F                 Login
           B
R
           A
O
     API   C
N                Domain
           K
T
           E
E
N
D
           N
           D      ...
                   VPS
RESTful API
●   Ресурсы (объекты)
●   URI – идентификатор ресурса
●   HTTP методы (POST, GET, PUT, PATCH,
    DELETE)
●   Формат передачи данных на выбор (HTML,
    XML, JSON, …)
●   Метаданные
REST + Dancer
post '/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 { … };
Dancer
dancer/                     ...
  +-- 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/
Routes
get '/domain' => sub : Auth(
     Admin Marketing Reseller
){
     Chimera::API::Domain->get(params());
};
Routes - Authentication
use 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
Routes - Controllers
get '/domain' => sub : Auth(
     Admin Marketing Reseller
){
     Chimera::API::Domain->get(params());
};
Controllers
Chimera/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
Server-side programs
use 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
…;
Тестирование



<sam> Doing the tests afterwards is like putting
a condom on after you've come.
Test-driven development
●   Добавить тест
●   Запустить тесты: убедиться, что новые тесты
    не проходят
●   Написать код
●   Запустить тесты: убедиться, что все тесты
    проходят
●   Рефакторинг
●   Повторить
Тестирование API
use Test::ChimeraAPI;
Test::ChimeraAPI::run_tests(
     {
          title => 'Create: normal mailbox',
          call => [
               POST => '/email' => %mailbox_details,
          ],
          expect => {
               http_code => HTTP_CREATED,
               data   => { success => 1 },
          },
     },
);
Тестирование API


t/ (master) $ prove -v api.t
1..78
ok 1 - Create: normal mailbox: HTTP code
ok 2 - Create: normal mailbox data is hashref as expected
ok 3 - Create: normal mailbox{success} data: scalar as expected
ok 4 - Create: normal mailbox{success} data: is '1'
ok 5 - Create: normal mailbox data all matches
...
Тестирование
1.Написать тест и код
2.Запустить тесты
3.Увидеть кучу непонятных ошибок...
4.Понять, что сервер не перезапустился...
5.Исправить ошибки
6.Вернуться к пункту 2
Тестирование
1.Написать тест и код
2.Запустить тесты
3.Увидеть кучу непонятных ошибок...
4.Понять, что сервер не перезапустился...
5.Исправить ошибки
6.Вернуться к пункту 2
Dancer::Test
●   Test::ChimeraAPI::request()
    –   request_remote() - if $ENV{CHIMERA_SERVER}
        ●   LWP::UserAgent::request()
    –   request_internal()
        ●   Dancer::Test::dancer_response()
Dancer::Test - плюсы
●   Не нужно запускать сервер:
    –   Держать открытую вкладку
    –   Ждать рестарта
    –   Получать ошибки соединения
    –   Не отвлекаешься от процесса кодирования
●   Загружаются только нужные приложения
Dancer::Test - минусы
●   Условия менее близки к реальным
●   Загрузка приложений при каждом запуске
    теста → общее время тестирования выше
Test::Class
●   Фреймворк для представления тестов в
    виде классов
●   Удобно для тестирования ОО-кода
●   При работе с большим количеством тестов

Curtis (Ovid) Poe

http://www.modernperlbooks.com/mt/2009/03/organizing-test-suite
s-with-testclass.html

http://www.slideshare.net/Ovid/testing-with-testclass
Test::Class - плюсы
●   Однократная загрузка Dancer-приложений
    –   Может пригодиться для любых “тяжёлых”
        модулей
●   Много других “плюшек”
    –   Фазы подготовки / очистки
    –   Наследование
    –   Тестирование отдельных классов через prove
    –   Тестирование отдельных методов
    –   и т.д.
Test::Class - минусы
●   Требует изучения (в том числе и
    исходников)
●   Нужна реорганизация тестов
Test::Class - тесты
t/
     +-- class.t
     +-- lib/
        +-- Email/
           +-- Test/
                +-- Create.pm
                +-- Delete.pm
                +-- Get.pm
                +-- Patch.pm
                +-- Put.pm
                +-- Rename.pm
                +-- API.pm
class.t
#!/usr/bin/env perl
use lib::abs '../../../lib';
use our::way;


use Test::Class::Load lib::abs::path('lib');
Удалённые системы

                    Тесты



                API-сервер


domains     cpanel                        vps

                         Сторонние API
Registrar
            cPanel API                   VPS API
  API
Удалённые системы
●   Взаимодействие по сети
    –   Медленно
    –   Необходимо подключение к Интернет
    –   Поддержка тестовых серверов
●   Тормоза самих систем
    –   Создание VPS занимает ~1 мин
●   Конфликты при одновременном запуске
    тестов
Mock-тестирование
●   Пишем тесты и код
●   Доводим до рабочего состояния с
    использованием реальной удалённой
    системы
●   Записываем ответы сервера
●   Подменяем записанными ответами
    реальные
Mock-тестирование - протоколы
●   HTTP (LWP::UserAgent) – большая часть
    систем
●   Другие
Test::LWP::Recorder
●   Запись ответов сервера в файлы
    $request_md5sum
●   Подстановка записанных ответов
Test::LWP::Recorder
GET http://foreign.api/something/:id - $resp1
PATCH http://foreign.api/something/:id - $resp2
GET http://foreign.api/something/:id - $resp1 (а
должен быть $resp3)
Test::LWP::UserAgent
●   Inspired by Test::Mock::LWP::Dispatch by Yury
    Zavarin
●   Активно (более-менее) разрабатывается
●   Расширяет возможности LWP::UserAgent
●   Содержит интересные и полезные фичи

    http://www.perladvent.org/2012/2012-12-12.html
Test::LWP::UserAgent –
             register_psgi

$useragent->register_psgi($hostname, $app);


Используется любой PSGI-совместимый
фреймворк.
Например, Dancer :)
Но...

                       Тесты
Процесс

                   API-сервер


   domains     cpanel                        vps

                            Сторонние API
   Registrar
               cPanel API                   VPS API
     API
Но...

                       Тесты
Процесс

                   API-сервер
                    API-сервер


   domains     cpanel                        vps

                            Сторонние API
   Registrar
               cPanel API                   VPS API
     API
В Dancer всё глобально!
●   Конфигурация (settings в Dancer::Config)
    –   Serializer
●   Хуки (singleton
    Dancer::Factory::Hook->hooks)
    –   Аутентификация
●   Переменные (vars в Dancer::SharedData)
    –   Используются внутри нашего API, не
        определены в mocked API
Инжекция mock-данных
●   Test::ChimeraAPI::Mocking
    –   Подготовка mocked классов в секции startup()
    –   Глобальная переменная $Mock::Something::API
●   Mock-данные инжектированы в сам
    тестовый класс
●   Mock-класс проверяет наличие данных и
    возвращает их в порядке timestamp или
    отправляет запрос к серверу
●   Запись в файл при необходимости
Юнит-тестирование
Юнит-тестирование – это тестирование
каждого неделимого блока
функциональности в изоляции – не только
возвращаемых значений для различных
аргументов, но также взаимодействия этих
блоков с другими частями приложения
путём имитации работы этих частей.
        http://tinyurl.com/c4rweaw
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;
}
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();
}
Devel::Cover
●   Оценка покрытия тестами
●   $^P ($PERLDB) == 0x104;
    –   Выключена оптимизация
●   Не работают атрибуты :(
Devel::Cover
package 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
Документация проекта
●   POD
●   Pod::HTML5::Browser
Код:
https://github.com/LoonyPandora/Pod-HTML5-Browser

Презентация:
https://speakerdeck.com/loonypandora/documentation-for-fun-and-profit
Спасибо!

Илья Чесноков <chesnokov.ilya@gmail.com>
Вопросы?

Contenu connexe

Tendances

Автоматизация функционального тестирования REST API
Автоматизация функционального тестирования REST APIАвтоматизация функционального тестирования REST API
Автоматизация функционального тестирования REST APIPavel Asanov
 
Система обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyСистема обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyRegn
 
Продвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевПродвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевYandex
 
Автоматизация тестирования WEB API
Автоматизация тестирования WEB APIАвтоматизация тестирования WEB API
Автоматизация тестирования WEB APISQALab
 
Использование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияИспользование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияSQALab
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneCodeFest
 
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Ontico
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полнойОмские ИТ-субботники
 
Инструменты и лайфхаки тестирования REST API
Инструменты и лайфхаки тестирования REST APIИнструменты и лайфхаки тестирования REST API
Инструменты и лайфхаки тестирования REST APISQALab
 
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»Yulia Tsisyk
 
How to build solid CI-CD pipeline / Илья Беда (beda.software)
How to build solid CI-CD pipeline / Илья Беда (beda.software)How to build solid CI-CD pipeline / Илья Беда (beda.software)
How to build solid CI-CD pipeline / Илья Беда (beda.software)Ontico
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
Скриптовой язык Groovy и его применение в рамках разработки ПО
Скриптовой язык Groovy и его применение в рамках разработки ПОСкриптовой язык Groovy и его применение в рамках разработки ПО
Скриптовой язык Groovy и его применение в рамках разработки ПОFedor Malyshkin
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverIgor Khrol
 
BDD girls Battle: Cucumber VS. JBehave
BDD girls Battle: Cucumber VS. JBehaveBDD girls Battle: Cucumber VS. JBehave
BDD girls Battle: Cucumber VS. JBehaveSQALab
 
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"Yulia Tsisyk
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demandSQALab
 
Концепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикадКонцепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикадSQALab
 

Tendances (19)

Автоматизация функционального тестирования REST API
Автоматизация функционального тестирования REST APIАвтоматизация функционального тестирования REST API
Автоматизация функционального тестирования REST API
 
Система обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyСистема обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на Groovy
 
Продвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевПродвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр Кошелев
 
Автоматизация тестирования WEB API
Автоматизация тестирования WEB APIАвтоматизация тестирования WEB API
Автоматизация тестирования WEB API
 
Использование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестированияИспользование Open Source инструментов для автоматизации тестирования
Использование Open Source инструментов для автоматизации тестирования
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows Phone
 
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
 
Инструменты и лайфхаки тестирования REST API
Инструменты и лайфхаки тестирования REST APIИнструменты и лайфхаки тестирования REST API
Инструменты и лайфхаки тестирования REST API
 
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
Юлия Цисык «RESTFul API в вашем.NET приложении: как, зачем и почему?»
 
How to build solid CI-CD pipeline / Илья Беда (beda.software)
How to build solid CI-CD pipeline / Илья Беда (beda.software)How to build solid CI-CD pipeline / Илья Беда (beda.software)
How to build solid CI-CD pipeline / Илья Беда (beda.software)
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
Скриптовой язык Groovy и его применение в рамках разработки ПО
Скриптовой язык Groovy и его применение в рамках разработки ПОСкриптовой язык Groovy и его применение в рамках разработки ПО
Скриптовой язык Groovy и его применение в рамках разработки ПО
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriver
 
BDD girls Battle: Cucumber VS. JBehave
BDD girls Battle: Cucumber VS. JBehaveBDD girls Battle: Cucumber VS. JBehave
BDD girls Battle: Cucumber VS. JBehave
 
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
Никита Цуканов "Параллелизм и распределённые вычисления на акторах с Akka.net"
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demand
 
Концепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикадКонцепция QaAPI: взгляд на тестирование с другой стороны баррикад
Концепция QaAPI: взгляд на тестирование с другой стороны баррикад
 

En vedette

«Автоматизация функционального тестирования REST API: секреты, тонкости и под...
«Автоматизация функционального тестирования REST API: секреты, тонкости и под...«Автоматизация функционального тестирования REST API: секреты, тонкости и под...
«Автоматизация функционального тестирования REST API: секреты, тонкости и под...2ГИС Технологии
 
Автоматизация функционального тестирования REST API: секреты, тонкости и подв...
Автоматизация функционального тестирования REST API: секреты, тонкости и подв...Автоматизация функционального тестирования REST API: секреты, тонкости и подв...
Автоматизация функционального тестирования REST API: секреты, тонкости и подв...SQALab
 
архітектура Web сервісів
архітектура Web сервісівархітектура Web сервісів
архітектура Web сервісівВітя Дзундза
 
Роман Акинфеев «Разработка RESTful API with all bells and whistles»
Роман Акинфеев «Разработка RESTful API with all bells and whistles»Роман Акинфеев «Разработка RESTful API with all bells and whistles»
Роман Акинфеев «Разработка RESTful API with all bells and whistles»DevDay
 
Автоматизированное тестирование WEB сервисов
Автоматизированное тестирование WEB сервисовАвтоматизированное тестирование WEB сервисов
Автоматизированное тестирование WEB сервисовSQALab
 
CodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестирования
CodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестированияCodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестирования
CodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестированияCodeFest
 
«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС
«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС
«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС2ГИС Технологии
 
Лайфхаки ручного тестирования на мобилках
Лайфхаки ручного тестирования на мобилкахЛайфхаки ручного тестирования на мобилках
Лайфхаки ручного тестирования на мобилкахSQALab
 

En vedette (8)

«Автоматизация функционального тестирования REST API: секреты, тонкости и под...
«Автоматизация функционального тестирования REST API: секреты, тонкости и под...«Автоматизация функционального тестирования REST API: секреты, тонкости и под...
«Автоматизация функционального тестирования REST API: секреты, тонкости и под...
 
Автоматизация функционального тестирования REST API: секреты, тонкости и подв...
Автоматизация функционального тестирования REST API: секреты, тонкости и подв...Автоматизация функционального тестирования REST API: секреты, тонкости и подв...
Автоматизация функционального тестирования REST API: секреты, тонкости и подв...
 
архітектура Web сервісів
архітектура Web сервісівархітектура Web сервісів
архітектура Web сервісів
 
Роман Акинфеев «Разработка RESTful API with all bells and whistles»
Роман Акинфеев «Разработка RESTful API with all bells and whistles»Роман Акинфеев «Разработка RESTful API with all bells and whistles»
Роман Акинфеев «Разработка RESTful API with all bells and whistles»
 
Автоматизированное тестирование WEB сервисов
Автоматизированное тестирование WEB сервисовАвтоматизированное тестирование WEB сервисов
Автоматизированное тестирование WEB сервисов
 
CodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестирования
CodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестированияCodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестирования
CodeFest 2014. Павлов И. — Как делать прототипы в автоматизации тестирования
 
«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС
«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС
«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС
 
Лайфхаки ручного тестирования на мобилках
Лайфхаки ручного тестирования на мобилкахЛайфхаки ручного тестирования на мобилках
Лайфхаки ручного тестирования на мобилках
 

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

Building better APIs on rails
Building better APIs on railsBuilding better APIs on rails
Building better APIs on railsRoman Gorel
 
Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.Sphere Consulting Inc
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayAndrey Rebrov
 
От Make к Ansible
От Make к AnsibleОт Make к Ansible
От Make к AnsibleIvan Grishaev
 
Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Ontico
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPITimur Shemsedinov
 
Psgi app
Psgi appPsgi app
Psgi appund3f
 
Solit 2012, Enterprise разработка PHP приложений, Иван Захарченко
Solit 2012, Enterprise разработка PHP приложений, Иван ЗахарченкоSolit 2012, Enterprise разработка PHP приложений, Иван Захарченко
Solit 2012, Enterprise разработка PHP приложений, Иван Захарченкоsolit
 
Behat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и MinkBehat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и Minktyomo4ka
 
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)Ontico
 
PaaS, выделенные сервера, облако и снова PaaS
PaaS, выделенные  сервера, облако и снова PaaSPaaS, выделенные  сервера, облако и снова PaaS
PaaS, выделенные сервера, облако и снова PaaSAlexey Vakhov
 
Пластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьПластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьMoscow.pm
 
Обзор Continuous integration инструментов
Обзор Continuous integration инструментовОбзор Continuous integration инструментов
Обзор Continuous integration инструментовVitalii Morvaniuk
 

Similaire à Опыт разработки и тестирования RESTful JSON сервиса (20)

Building better APIs on rails
Building better APIs on railsBuilding better APIs on rails
Building better APIs on rails
 
Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.Roman Gorel: Building better APIs on Rails.
Roman Gorel: Building better APIs on Rails.
 
Building deployment pipeline - DevOps way
Building deployment pipeline - DevOps wayBuilding deployment pipeline - DevOps way
Building deployment pipeline - DevOps way
 
От Make к Ansible
От Make к AnsibleОт Make к Ansible
От Make к Ansible
 
бегун
бегунбегун
бегун
 
Bazhin 1 zal
Bazhin 1 zal Bazhin 1 zal
Bazhin 1 zal
 
Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)Компиляция скриптов PHP (Алексей Романенко)
Компиляция скриптов PHP (Алексей Романенко)
 
бегун
бегунбегун
бегун
 
Chef
ChefChef
Chef
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
Psgi app
Psgi appPsgi app
Psgi app
 
PHP
PHPPHP
PHP
 
Scorex framework
Scorex frameworkScorex framework
Scorex framework
 
Solit 2012, Enterprise разработка PHP приложений, Иван Захарченко
Solit 2012, Enterprise разработка PHP приложений, Иван ЗахарченкоSolit 2012, Enterprise разработка PHP приложений, Иван Захарченко
Solit 2012, Enterprise разработка PHP приложений, Иван Захарченко
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Behat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и MinkBehat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и Mink
 
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
Legacy в коробочке. Dev-среда на базе Kubernetes / Илья Сауленко (Avito)
 
PaaS, выделенные сервера, облако и снова PaaS
PaaS, выделенные  сервера, облако и снова PaaSPaaS, выделенные  сервера, облако и снова PaaS
PaaS, выделенные сервера, облако и снова PaaS
 
Пластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьПластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать жить
 
Обзор Continuous integration инструментов
Обзор Continuous integration инструментовОбзор Continuous integration инструментов
Обзор Continuous integration инструментов
 

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

  • 1. Опыт разработки и тестирования RESTful JSON сервиса
  • 2. Требования к системе ● Удобство для реселлеров ● Возможность брендирования ● Гибкость и возможность расширения за счет подключаемых модулей
  • 3. Реализация Customer F Login B R A O API C N Domain K T E E N D N D ... VPS
  • 4. RESTful API ● Ресурсы (объекты) ● URI – идентификатор ресурса ● HTTP методы (POST, GET, PUT, PATCH, DELETE) ● Формат передачи данных на выбор (HTML, XML, JSON, …) ● Метаданные
  • 5. REST + Dancer post '/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. Dancer dancer/ ... +-- 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. Routes get '/domain' => sub : Auth( Admin Marketing Reseller ){ Chimera::API::Domain->get(params()); };
  • 8. Routes - Authentication use 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 - Controllers get '/domain' => sub : Auth( Admin Marketing Reseller ){ Chimera::API::Domain->get(params()); };
  • 10. Controllers Chimera/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 programs use 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 putting a condom on after you've come.
  • 13. Test-driven development ● Добавить тест ● Запустить тесты: убедиться, что новые тесты не проходят ● Написать код ● Запустить тесты: убедиться, что все тесты проходят ● Рефакторинг ● Повторить
  • 14. Тестирование API use Test::ChimeraAPI; Test::ChimeraAPI::run_tests( { title => 'Create: normal mailbox', call => [ POST => '/email' => %mailbox_details, ], expect => { http_code => HTTP_CREATED, data => { success => 1 }, }, }, );
  • 15. Тестирование API t/ (master) $ prove -v api.t 1..78 ok 1 - Create: normal mailbox: HTTP code ok 2 - Create: normal mailbox data is hashref as expected ok 3 - Create: normal mailbox{success} data: scalar as expected ok 4 - Create: normal mailbox{success} data: is '1' ok 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) Poe http://www.modernperlbooks.com/mt/2009/03/organizing-test-suite s-with-testclass.html http://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 perl use lib::abs '../../../lib'; use our::way; use Test::Class::Load lib::abs::path('lib');
  • 26. Удалённые системы Тесты API-сервер domains cpanel vps Сторонние API Registrar cPanel API VPS API API
  • 27. Удалённые системы ● Взаимодействие по сети – Медленно – Необходимо подключение к Интернет – Поддержка тестовых серверов ● Тормоза самих систем – Создание VPS занимает ~1 мин ● Конфликты при одновременном запуске тестов
  • 28. Mock-тестирование ● Пишем тесты и код ● Доводим до рабочего состояния с использованием реальной удалённой системы ● Записываем ответы сервера ● Подменяем записанными ответами реальные
  • 29. Mock-тестирование - протоколы ● HTTP (LWP::UserAgent) – большая часть систем ● Другие
  • 30. Test::LWP::Recorder ● Запись ответов сервера в файлы $request_md5sum ● Подстановка записанных ответов
  • 31. Test::LWP::Recorder GET http://foreign.api/something/:id - $resp1 PATCH http://foreign.api/something/:id - $resp2 GET 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::Cover package 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.
  • 45.