Пользователь
0,0
рейтинг
29 апреля 2014 в 13:44

Разработка → Тестирование отдельных Symfony 2 бандлов из песочницы

TDD*, Symfony*, PHP*
Начну с коротенькой предыстории. Была у меня задача написать резерватор для номеров в отеле, я полез на всеми нами любимый packagist, в поисках готового решения и, к моему глубокому разочарованию, не нашел ничего. Ну, надо сделать — сделаем. Код написан, покрыт функциональными тестами в приложении. Через пару недель я решил выложить написанный бандл на github. Но передо мной встал вопрос: при тестировании отдельного бандла у нас нет самого приложения. Начал гуглить, и опять не нашел ничего стоящего. В общем пришлось собирать информацию по крупицам, и сейчас я хочу поделиться своим опытом с вами.

Зависимости


Первое, что нам желательно сделать — создать новый репозиторий для нашего бандла и добавить в него файлы к нему относящиеся. Наш бандл, конечно-же, имеет внешние зависимости. Для их разрешения мы будем использовать composer. У меня он установлен глобально сделайте поправку на это. Начнем:

$ composer init #Следуем указаниям


Мы инициализаровали наш проект. В корневой директории был создан файл composer.json. В нем есть несколько секций интересных нам: require, require-dev, suggest. Пройдемся по каждой из них:
  • require — то, без чего наш проект не может работать
  • require-dev — то, что мы используем для разработки и тестирования
  • suggest — тут вы можете сказать, что ваш бандл может работать, например, не только с ORM но и ODM

Установим нужные компоненты командой
$ composer install

Хорошо, с зависимостями разобрались.

Ядро


Для тестирования сервисов и функционального тестирования нам понадобится практически полнофункциональное приложение.
Автозагрузка классов

Нам понадобится создать свой bootstrap.php в директории с нашими тестами и указать, что phpunit должен использовать именно его.
<?php

use Doctrine\Common\Annotations\AnnotationRegistry; //Только если вы используете Doctrine и анотации
use Composer\Autoload\ClassLoader;

/**
 * @var ClassLoader $loader
 */
$loader = require __DIR__.'/../vendor/autoload.php';

AnnotationRegistry::registerLoader(array($loader, 'loadClass')); //Только если вы используете Doctrine и аннотации

return $loader;


Еще раз хочу обратить ваше внимание на строку AnnotationRegistry::registerLoader(array($loader, 'loadClass'));. Мой бандл во всю использует Doctrine и аннотации и для меня было большим удивлением, когда я раз за разом получал исключение с тектом «Annotation can not be loaded».

Открываем наш phpunit.xml.dist и указываем где наш лежит наш bootstrap.php
<phpunit bootstrap="./Tests/bootstrap.php">

AppKernel и Консоль

Следующим шагом будет инициализация приложения. Я создал папку Tests/fixtures где будут лежать файлы относящиеся к нашему приложению для тестов. Ключевым классом любого symfony приложения является AppKernel, создадим его в папке Tests/fixtures/app
<?php

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class AppKernel extends Kernel
{
/**
 * @return array
 */
    public function registerBundles()
    {
        $bundles = array(
             //Указываем какие бандлы нам необходимы
        );

        return $bundles;
    }
    /**
     * @param \Symfony\Component\Config\Loader\LoaderInterface $loader
     */
    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__ . '/config/config.yml');
    }
} 

Дальше нам необходимо будет сконфигурировать наш контейнер, для этого создадим файл Tests/fixtures/app/config/config.yml.

Если вам нужна консоль, просто создайте файл Tests/fixtures/app/console со следующим содержанием:
#!/usr/bin/env php
<?php

// if you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
//umask(0000);

set_time_limit(0);

require_once __DIR__.'/../../bootstrap.php';
require_once __DIR__.'/AppKernel.php';

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;

$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';

if ($debug) {
    Debug::enable();
}

$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

Теперь укажем где находится ядро нашего приложения, добавляем в phpunit.xml.dist следующую директиву:
<php>
    <server name="KERNEL_DIR" value="Tests/Fixtures/app/" />
</php>


После этих нехитрых манипуляций мы получили наше тестовое приложение и открыли дорогу для использования Symfony\Bundle\FrameworkBundle\Test\WebTestCase, с помощью которого мы сможем тестировать наши сервисы и прочее в контексте Symfony 2 приложения.

Ознакомиться с полным кодом можно тут

PS: В следующей статье я постараюсь расрыть тонкости тестирования Doctrine в наших бандлах.
Iakov Mishchenko @sirMelifaro
карма
2,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

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

  • 0
    По-моему, всё это несколько избыточно.
    Если это бандл для Symfony, то использовать его без Symfony-приложения очень затруднительно.
    А значит, люди, которые будут его использовать, уже имеют проект с ядром Symfony и тесты будут запускать в контексте своего приложения.
    Если же нужно покрыть тестами специфический функционал, который должен работать сам по себе, то обычно делают разделяют классы или вовсе делают две репы: сама либа, которая, например резервирует номера, и бандл-обвязку для неё.
    И, соответственно, в репе либы пишем тесты, которые тестируют функционал либы, а в репе бандла тестируем, как работает обвязка, если это необходимо.
    • 0
      Если Вы используете бандл, то даже тесты можно не запускать (лично я не запускаю, а доверяюсь разработчикам). Но когда, дело встает за разработкой open source бандла, и его сборкой (допустим при помощи Travis), то это очень даже логично.

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