Тестирование → Автоматизированное тестирование
Это вторая запись из серии, посвящённой тестам, первая находится тут. В ней будет описан процесс установки и настройки функционального тестирования в Symfony2 с использованием Behat и Mink
Для начала, наверное, стоит рассказать о том, что такое эти Behat и Mink, и с чем их едят. Первое - это библиотека, которая интерпретирует человеко-понятные сценарии и, собственно, выполняет их в виде тестов. Второе - это абстрактная библиотека эмулятора браузера, которая содержит множество готовых определений, используемых Behat-ом при разборе тестовых сценариев, характерных именно для общих задач браузера. Помимо этих специфических определений, Mink предоставляет объектно-ориентированных интерфейс, позволяющий общаться с браузером. Сложно, конечно, описать это в двух словах, нужно самому посмотреть и пощупать :)
Сперва создадим пустой проект или же будем считать, что он уже существует. Я не стал особо заморачивать себе голову и скачал с офсайта Symfony Standard 2.1.7 without vendors. Установкой всех необходимых библиотек будет заниматься composer, а запускается сей процесс (установки) буквально одним взмахом левой пятки.
1 | php composer.phar install
|
Ну а теперь займёмся настройкой проекта для тестирования. В первую очередь подправим файл composer.json, добавив в него следующие штуки:
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"require-dev": {
"behat/symfony2-extension": "dev-master",
"behat/mink-extension": "dev-master",
"behat/mink-browserkit-driver": "dev-master",
"behat/mink-goutte-driver": "*",
"behat/mink-sahi-driver": "*"
},
"config": {
"bin-dir": "bin"
},
"minimum-stability": "dev"
}
|
Опишу по порядку то, что было сделано.
- require-dev - Здесь описываются пакеты, необходимые только для разработки и тестирования, для их закачки необходимо запустить команду install с опцией --dev, иначе эти пакеты скачаны не будут.
- Будет использоваться Symfony2Extension для интеграции Behat в проект. Там же, по ссылке, можно заглянуть в документацию на счёт behat/mink-extension или bin-dir, например.
- minimum-stability - данная опция указывает композеру как фильтровать пакеты по стабильности. По умолчанию установлено значение stable, т.е. скачиваться должны только стабильные версии пакетов. Обычно нет никакой необходимости трогать эту опцию, но так уж получилось, что на момент написания этого поста стабильная версия sahi-драйвера реализует не все функции, описанные в DriverInterface, что приводит к фатальной ошибке.
Запускаем установку пакетов
1 | php composer.phar install --dev
|
После инсталляции необходимых библиотек в корневой директории проекта необходимо создать файл behat.yml приблизительно такого содержания:
1 2 3 4 5 6 7 8 9 10 11 | default:
formatter:
name: progress
extensions:
Behat\Symfony2Extension\Extension:
mink_driver: true
Behat\MinkExtension\Extension:
base_url: 'http://your-domain.loc/'
default_session: sahi
goutte: ~
sahi: ~
|
- Если убрать секцию formatter, то в консоли будет отображаться информация по прохождению каждого шага тестовых сценариев. Можно, конечно, посмотреть на эти шаги в отдельности, но когда тестов много, то избыток информации начинает мешать, поэтому любоваться будем только полосой прогресса в виде точек :)
- base_url - здесь указывается URL, по которому робот будет ломится с нашими тестовыми инструкциями.
- default_session - здесь прописан использующийся по умолчанию драйвер браузера. Это может быть, например, sahi, который устанавливали в прошлой записи, или goutte - эмулятор браузера без графического интерфейса (headless browser), который работает быстрее того-же sahi, только вот javascript ему не по зубам. Более подробная информация находится тут → Different Browsers - Drivers
- Про настройку тестового окружения как-нибудь в другой раз. Для примера обойдёмся и без него.
Создадим директорию, в которой будут находиться тестовые сценарии и класс FeatureContext. Для этого выполним команду:
1 | sh bin/behat --init @YourBundleName
|
В указанном бандле создастся директория Features. В файле FeatureContext.php необходимо заменить родительский класс BehatContext на MinkContext, поскольку тестироваться будет веб-приложение.
Создадим в папке Features файл testComment.feature, в котором напишем следующие сценарии. Проверим, для начала, просто стартовую страницу, после чего перейдём по ссылке в определённую запись и оставим там тестовый комментарий, убедившись в том, что комментарий сохранился.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Feature: testComment
Start page opening
Scenario: Successfully opening start page
Given I am on "/"
Then I should see "Zend-blog-2"
Scenario: Add comment
Given I am on "/"
And I follow "Установка Sahi"
Then I should see "Адрес электронной почты нигде не отображается"
When I fill in "Имя:" with "testname"
And I fill in "E-mail:" with "test@example.org"
And I fill in "Website:" with "http://example.org"
And I fill in "Текст комментария:" with "TEST MESSAGE"
And I press "Добавить комментарий"
Then I should see "TEST MESSAGE" in the "div#all-comments" element
|
Запустим тест
1 | sh bin/behat @YourBundleName
|
В случае успеха увидим что-то вроде изображённого ниже. sahi-драйвер я использовал неспроста, т.к. комментарии добавляются только посредством AJAX, информация же, отправленная простым сабмитом формы попадает прямиком в спамную таблицу БД, о чём добропорядочные человеки, но с вырубленным яваскриптом, предупреждены заранее.
P.S. Скажу несколько слов ещё относительно тестов в общем. Они нужны! Если сайт не совсем примитивный и содержит некоторое количество связанных друг с другом компонентов, то не так уж и редко возникают ситуации, когда после незначительных изменений в процессе регистрации пользователя ломается, например, отправка писем, связанных с оформлением заказа. Или, например, случайно обнаружить, что уже полгода как sitemap.xml автоматически не обновляется. Конечно, кто-то скажет, что это всё можно и самому проклацать... Но пусть уж этим занимается робот, не знающий усталости и лени, тем более, что тестовых сценариев со временем будет всё больше и больше (если покрывать ими весь функционал веб-приложения). Даже если попадётся ответственный тестировщик, то не факт, что выполняя несколько часов к ряду заданные тесты, он не пропустит того факта, что, допустим, общая сумма заказа не равна сумме стоимостей товара и доставки.
P.P.S. Упомяну так-же, что и автоматизированные тесты не являются панацеей. Во первых, их пишут те же самые люди, подверженные ошибкам. Во вторых - обычный пользователь всегда умудрится произвести на сайте такие действия, о которых разработчик не то, что не догадывался в процессе написания кода и тестов, но и воспроизвести их не сможет длительное время. На предмет таких событий надо поглядывать хоть изредка в логи сервера. Успешное прохождение всех тестов не означает наверняка, что всё с приложением хорошо, но вот отрицательный результат - это уже явное указание на какие-нибудь неполадки.
Полезные ссылки:
Комментарии
А Behat/Mink у меня, скорее, исторически получились. Доклады на конференции, да и указание от работодателя, что их используем :) Я не юзал встроенные функциональные тесты из симфони, но беглый обзор по документации показывает, что тамошний краулер просто парсит ответ, а значит, javascript отпадает (т.е. определённую часть функционала просто невозможно проверить).
Естественно, я могу ошибаться по незнанию и недоумию, да хотя бы и потому, что ни разу использовал :)
Есть сайты A, B, C (одинаковый функционал, но разные языки). Нужно проверить ключевые моменты работы каждого из них.
Реализация через "Примеры" не подходит потому что может добавиться например сайт D и тогда в каждый чек-лист придется добавлять его.