Автотесты Codeception для вебсервиса

Сразу отмечу что пост посвящается начинающим тестировщикам, заинтересованным в автоматизации тестирования. Мне уже доводилось рассказывать про Codeception. Этот отличный фреймворк позволяет проводить автоматизированное тестирование web-приложений и не только. Сценариев использования очень много, в качестве примера я хотел бы показать автотесты для какого-нибудь Open Source вебсервиса.

После недолгих поисков я набрел на:

Что он делает? Передаваемые в URL параметры преобразуются в JSON объект. Результат запроса, возвращается в таком виде:

Конечно какой-нибудь живой API будет возвращать что-то действительно нужное, но для начинающих этого достаточно. Его мы и протестируем.

Для тех кто не знает что такое вебсервис

Говоря простым языком, это возможность получить различные данные из вашего проекта через веб. Небольшой пример. Предположим у вас дико популярный международный магазин цветов с огромным товарным ассортиментом. Товаров так много, что вы решаете создать реферальную систему и продавать свои товары через посредников. Чтобы посредники получили доступ к вашему ассортименту, создается API. Теперь посредник может отправить GET запрос и получить список доступных товаров из вашего ассортимента. Отправить POST если ему удалось что-то продать и т.д. Теперь я думаю понятно что можно извлечь из Youtube API или Google Maps API. Хорошое объяснение в чем разница между API и вебсервисом.

Начинаем тестирование

Для начала нужно прикинуть как мы собираемся протестировать этот веб-сервис. Так сказать тест-план. В силу того что я пишу лишь мануал, я покрою только основной сценарий и не буду останавливаться на негативных. После вы сами сможете проработать пустой запрос, цифровые значения, спец-символы, длинные строки и другие понравившиеся тест-кейсы.

Дальше рекомендую прочитать документацию Codeception.

Особенно Introdution и Getting Started.

Настройка Codeception

Оговорка: Пример показан для Linux и ему подобных систем. Еще раз подчеркну, что знать Linux полезно всем тестировщикам.

  1. Это все таки PHP фреймворк, так что нам будет нужен PHP. Устанавливаем версию 5.6.*, нет смысла ставить ниже потому что фреймворк уже не поддерживает предыдущие. Насчет  PHP 7 тоже не уверен, думаю она пока только в планах.
  2. Все варианты инсталляции Codeception есть здесь. Я выбираю пакет *.phar , в котором все собрано в один исполняемый файл, это удобно для демонстрации. Но рекомендую установить фреймворк через Composer, тогда Codeception можно будет устанавливать из зависимостей вашего проекта.

Дальше подготовим наш тестовый проект. Создадим папку проекта, зайдем в нее и запустим команду bootstrap

Codeception автоматически создаст нужные папки и файлы конфигурации. Вот пример созданного проекта и его файлов

Внутри папок acceptance, functional, unit будут лежать автотесты. Теперь нам нужно изменить конфиг функциональных тестов

В конфиге мы подключаем 3 модуля.

  • Asserts — Здесь подключаются assert методы
  • PhpBrowser — Аналог браузера, на основе Guzzle. Не имеет интерфейса и не поддерживает JS, но хорош когда нужно быстро проверить наличие элемента или например роутинг. В параметр url предоставляется дефолтный тестовый адрес
  • \Helper\Functional — Это предустановленный модуль(хэлпер), который можно редактировать и добавлять собственные тестовые методы

После редактирования конфига обязательно запускаем команду build

После выполнения команды,  все созданные в хэлперах методы становятся доступными для использования в автотестах.

Пишем автотесты

Codeception может автоматически сгенерить тест с небольшим «каркасом».

Эта команда сгенерирует новый файл echoJsonCest.php в директории функциональных тестов вашего проекта. В нем и будут лежать наши автотесты.

Так выглядит наш сгенерированный файл. Все публичные функции будут запущены как тесты. Функции _before и _after аналогичны тем что есть во всех xUnit фреймоврках и помогают сделать действия, которые нужны перед или после каждого теста. Функцию tryToTest мы переименуем в нужный нам тест.

Как мы будем тестировать? Сценарий примерно такой

  • Открываем URL в браузере
  • Граббим оттуда текст из селектора
  • Преобразуем его в JSON объект
  • Проверяем что введенные в URL данные правильно попали в JSON объект

Основные методы будут использоваться из модуля PhpBrowser. В итоге мы получаем вот такой тест

Оптимизируем

Созданный автотест плох. Открывать страницу, чтобы потом оттуда грабить response не правильно. Можно сделать намного удобнее, читабельнее и правильнее.

Для этого мы задействуем созданный ранее хэлпер Functional.php

В хэлпере мы унаследуем PhpBrowser и тем самым получим все его методы,  а также сможем их отредактировать. Дальше мы создаем кастомную функцию returnJsonResponse которая по url будет возвращать нам response. Причем получать response мы будем непосредственно из запроса, а не из полученной html страницы. Если более подробно, то мы будем использовать класс Guzzle и вызовем его метод request, а на выходе вернем Json объект из ответа вебсервиса.

Теперь, когда у нас есть удобный метод получения json response, мы можем сделать тест более понятным и красивым.

Не забываем также изменить конфиг, теперь нам не нужен PhpBrowser, ведь мы переопределили его в \Helper\Functional.

Запускаем команду build чтобы перегенерировать методы фреймворка. И теперь можно запустить сам тест

Результат выглядит так:

Вот и все. Остается покрыть все сценарии работы вебсервиса. Буду рад ответить на ваши вопросы в комментариях.

 

UPD. Спасибо Дмитрию за конструктивный коммент =)

Можно не наследовать PhpBrowser и вообще не писать свой хэлпер и поступить намного проще.

Для этого мы подключим модуль REST

Теперь у нас есть возможность использовать существующие методы, типа sendGET или sendPOST и другие. К тому же в модуле REST уже встроены специальные проверки и мы сможем обойтись без Assert модуля. Таким образом тест изменится:

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

 

2 Комментарии

  1. Дмитрий

    29.09.2016 в 08:54

    Добрый день.
    Зачем спускаться до уровня PhpBrowser и тем более Guzzle, когда есть REST-модуль с его методами sendGET, sendPOST, grabResponse?

    Зачем в хелпере наследовать модуль, когда его можно получить в любом методе:
    $phpBrowser = $this->getModule(‘PhpBrowser’);
    В таком случае функциональность хелпера не будет ограничена, останутся доступными хуки вроде _beforeSuite.

    По оптимизированному примеру returnResponse очень ограниченный — отправляет только GET, без параметров, да ещё ожидает всегда json в ответе. Плюс в метод зачем-то передаётся $I, который там не используется.

    • Андрей Ким

      29.09.2016 в 11:20

      Спасибо за конструктивный комментарий.

      1. До уровня PhpBrowser можно не опускаться. Да с REST модулем это гораздо проще. Спасибо я дополню статью.
      2. В хелпере я унаследовался от PhpBrowser чтобы расширять функционал. Я предполагаю что этот модуль будут использовать чаще всего и будет удобно в дальнейшем расширять его. И насколько я знаю, хуки по прежнему работают.
      3. returnResponse ограниченный да, я не задумывался над тем с чем можно столкнуться, потому что показывал именно на одном примере. естественно метод можно улучшать. $I избыточен, спасибо исправлю.

Добавить комментарий