Pull to refresh

Установка и настройка функционального тестирования в Symfony2 с помощью Behat и Mink

TDD *
Sandbox
Идея о том, что веб-приложения написанные на PHP нуждаются в тестировании, не нова и постепенно входит в повседневную практику разработчиков. PHPUnit стал стандартом тестирования PHP приложений, в том числе и в новом фреймворке Symfony2. В установке из symfony-standard в AcmeDemoBundle для тестирования контроллера используется именно он1. Я хочу рассказать о альтернативном пути тестирования функционала, с применением Behat и Mink, и описать подробности процесса установки и тестирования.

Установка фреймворка


Для начала нам понадобятся рабочая связка Apache + PHP 5.3, с поддержкой локальных хостов,intl, git. Не буду останавливаться на процессе их установки и настройки — в сети достаточно информации как это сделать для каждой отдельно взятой системы, к тому же у разработчика все это уже скорее всего установлено (лично я полагаю, что разработку нужно вести на локальной или тестовой машине, а не на работающем сайте)
Далее — нам понадобится скачать и настроить наш проект с GitHub. Откроем терминал, перейдем в папку, где расположены локальные сайты.

$ cd ~/Sites
$ git clone github.com/symfony/symfony-standard.git
$ cd symfony-standard


Проверяем, подходит ли Ваш Apache+PHP для работы в Symfony2, для этого используем поставляемый с фреймворком скрипт:
$ php app/check.php
Если необходимы какие либо настройки или модули — устанавливаем и настраиваем.

Скачиваем собственно фреймворк (он располагается по умолчанию в папке vendors). Для этого набираем в терминале:
$ php bin/vendors install
После этого нужно настроить отображения проекта в броузере, для чего я вношу изменения в два файла (пути у Вас могут быть иными, я работаю на Mac Os 10.6 с стандартно поставляемым apache):
— в /etc/hosts добавляю строчку, обозначающую, что проект у меня локальный, и в сети его искать нечего:
...
127.0.0.1 symfony-standard

— в /etc/apache2/extra/httpd-vhosts.conf

<VirtualHost *:80>
    DocumentRoot "/Users/Standart-User/Sites/symfony-standard/web"
    ServerName t0002.loc
	<Directory "/Users/Standart-User/Sites/symfony-standard/web">
		Options Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
		AllowOverride All
	</Directory>
</VirtualHost>

Рестартуем Apache, и проверяем результат работы в броузере, открыв страницу symfony-standard/app_dev.php. Если все сделано правильно — получаем следующую картинку:
Стартовая страница symfony-standard

А при вводе в терминале в корневой папке проекта
$ php app/console
получаем список команд фреймворка. Отмечаем для себя что в этом списке пока отсутствует команда behat после перечисления Options в блоке Available commands

На этом этапе можно считать что с установкой Symfony2 мы справились.

Установка Mink и Behat для тестирования


Так как все проекты, над которыми я работаю, лежат у меня в папке ~/Sites и я не хочу для каждой установки Symfony2 фреймворка устанавливать бандлы для тестирования — я сделал это один раз в папку ~/Sites/testsuite.behat, а затем подключаю ее содержимое в свои проекты.

Для удобства установки я создал проект на GitHub, оттуда можно его и установить:

    $ cd ~/Sites
    $ git clone https://github.com/livsi/testsuite.behat.git
    $ cd testsuite.behat


Фактически он содержит набор субмодулей и инструкцию как это все подвязать к своему рабочему проекту на Symfony2. После клонирования репозитория нам необходимо скачать субмодули. Для этого — выполняем команду:
    $ git submodule update --init


Все, с установкой набора для тестирования почти закончили. Так как активными ветками в Behat и Mink являются ветки develop, а не master — нужно перейти в них и переключиться вручную.
    $ cd ~/Sites/testsuite.behat/vendor/Behat/Behat/
    $ git checkout --track -b develop origin/develop
    $ cd ~/Sites/testsuite.behat/vendor/Behat/Mink/
    $ git checkout --track -b develop origin/develop


Подключаем testsuite.behat к проекту symfony-standart


Это наиболее быстрый этап, так как нам ничего не нужно получать из сети, только править конфигурационные файлы в проекте symfony-standart. Инструкции приложены к скачанному ранее коду, находятся в файле README.md

Открываем файл ~/Sites/symfony-standart/app/autoload.php и добавляем следующие строки (нужно подправить пути соответственно Вашим собственным) для подгрузки бандлов тестирования в проект symfony2:
// app/autoload.php
    $loader->registerNamespaces(array(
    // ...
    'Behat\BehatBundle' => '/Users/Standart-User/Sites/testsuite.behat/vendor',
    'Behat\Behat'       => '/Users/Standart-User/Sites/testsuite.behat/vendor/Behat/Behat/src',
    'Behat\Gherkin'     => '/Users/Standart-User/Sites/testsuite.behat/vendor/Behat/Gherkin/src',
    'Behat\Mink'        => '/Users/Standart-User/Sites/testsuite.behat/vendor/Behat/Mink/src',
    'Behat\MinkBundle'  => '/Users/Standart-User/Sites/testsuite.behat/vendor',
    'Goutte'            => '/Users/Standart-User/Sites/testsuite.behat/vendor/Goutte/src',
    'Zend'              => '/Users/Standart-User/Sites/testsuite.behat/vendor/Zend/library',
    'Behat\SahiClient'  => '/Users/Standart-User/Sites/testsuite.behat/vendor/Behat/SahiClient/src',
    'Buzz'              => '/Users/Standart-User/Sites/testsuite.behat/vendor/Buzz/lib',
// ...

В файле ~/Sites/symfony-standart/app/AppKernel.php включаем два основных бандла — BehatBundle и BehatMinkBundle:
// app/AppKernel.php
    if (in_array($this->getEnvironment(), array('dev', 'test'))) {
    // ...
    $bundles[] = new Behat\BehatBundle\BehatBundle();
    $bundles[] = new Behat\MinkBundle\BehatMinkBundle();
    // ...
    }

Прописываем обязательные параметры в ~/Sites/symfony-standart/app/config/config_dev.yml:
# app/config/config_dev.yml
framework:
    test:       ~

# ...

behat: ~

behat_mink:
    base_url:  http://symfony-standart/app_test.php/
    goutte:     ~   # enable both Goutte
    sahi:       ~   # and Sahi session

Проверяем, что все установлено и настроено правильно, для этого из корня проекта symfony-standart в терминале вводим:
$ php app/console
получаем список команд фреймворка, в котором теперь должна присутствовать команда behat. Это означает, что все работает и необходимые бандлы подключены.

Собственно тестирование



Для создания каркаса тестирования для бандла выполняем в консоли из корня проекта команду:
$ php app/console behat:bundle --init Acme\\DemoBundle
Она создает в папке src/Acme/DemoBundle каталог Features/

Добавляем в него файл, который назовем feature1.feature со следующим содержанием:

# language: ru

Функционал: Первый тест для AcmeDemoBundle
  Тестируем реализованные возможности в демонстрационном бандле

  Сценарий: Открыть главную страницу в dev окружении и убедиться в ее существовании
    Допустим я на странице "/app_dev.php"
    Тогда код ответа сервера должен быть 200
    И я должен видеть "Congratulations! You have successfully installed a new Symfony application."
    И я должен видеть "Welcome!"
    
  Сценарий: Перейти с главной страницы на страницу по ссылке "Run The Demo"
    Допустим я на странице "/app_dev.php"
    Если я кликаю по ссылке "Run The Demo"
    Тогда я на странице "/app_dev.php/demo/"
    И код ответа сервера должен быть 200
    И я должен видеть "Available demos" 


Это и есть те самые функциональные тесты. Чтобы запустить тест — вводим в консоли команду:
$ php app/console behat --no-paths @AcmeDemoBundle и видим примерно следующий результат:
Результат тестирования AcmeDemoBundle symfony-standard

По скриншоту можно увидеть, что синтаксис вызова упростился: сначала от behat:test:bundle до behat:bundle, а теперь и до просто behat.

Справку по необходимым ключам консольной команды можно получить, набрав
app/console help behat

Потратив относительно немного времени на подключение Behat и Mink получаем значительный профит в виде простых и читабельных, наглядных тестов, которые пишутся на понятном языке. Они быстро пишутся и быстро выполняются.

Благодарности


Особая благодарность — Константину Кудряшову (хабраюзер everzet) за создание Behat и Mink, консультации их использованию, компании KnpLabs за спонсорскую помощь и содействие их автору, за поддержку проекта и дальнейшее его совершенствование.
Также большое спасибо разработчикам Symfony2 за мощный и удобный фреймворк, и подробнейшую документацию, которая помогает быстро его освоить.

Использованы материалы и репозитарии:






Пример тестирования контроллера с помощью PHPUnit (используется по умолчанию в symfony2):

namespace Acme\DemoBundle\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DemoControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = $this->createClient();

        $crawler = $client->request('GET', '/demo/hello/Fabien');

        $this->assertTrue($crawler->filter('html:contains("Hello Fabien")')->count() > 0);
    }
}


То же самое с помощью Behat
  Сценарий: Повторяем тест контроллера, проводимого через PHPUnit
    Допустим я на странице "/app_dev.php/demo/hello/Fabien"
    Тогда я должен видеть "Hello Fabien"


Не правда ли — тест на Behat более нагляден?
Tags: symfony2behatminkтестирование веб-приложенийbddtdd
Hubs: TDD
Total votes 21: ↑19 and ↓2 +17
Comments 33
Comments Comments 33

Popular right now

Top of the last 24 hours