[Из песочницы] Тестирование отдельных Symfony 2 бандлов
Начну с коротенькой предыстории. Была у меня задача написать резерватор для номеров в отеле, я полез на всеми нами любимый packagist, в поисках готового решения и, к моему глубокому разочарованию, не нашел ничего. Ну, надо сделать — сделаем. Код написан, покрыт функциональными тестами в приложении. Через пару недель я решил выложить написанный бандл на github. Но передо мной встал вопрос: при тестировании отдельного бандла у нас нет самого приложения. Начал гуглить, и опять не нашел ничего стоящего. В общем пришлось собирать информацию по крупицам, и сейчас я хочу поделиться своим опытом с вами.Зависимости Первое, что нам желательно сделать — создать новый репозиторий для нашего бандла и добавить в него файлы к нему относящиеся. Наш бандл, конечно-же, имеет внешние зависимости. Для их разрешения мы будем использовать composer. У меня он установлен глобально сделайте поправку на это. Начнем:$ composer init #Следуем указаниям
Мы инициализаровали наш проект. В корневой директории был создан файл composer.json. В нем есть несколько секций интересных нам: require, require-dev, suggest. Пройдемся по каждой из них:
require — то, без чего наш проект не может работать require-dev — то, что мы используем для разработки и тестирования suggest — тут вы можете сказать, что ваш бандл может работать, например, не только с ORM, но и ODM Установим нужные компоненты командой$ composer installХорошо, с зависимостями разобрались.Ядро Для тестирования сервисов и функционального тестирования нам понадобится практически полнофункциональное приложение.Автозагрузка классов Нам понадобится создать свой bootstrap.php в директории с нашими тестами и указать, что phpunit должен использовать именно его.
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
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
// 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 следующую директиву:
Ознакомиться с полным кодом можно тут PS: В следующей статье я постараюсь расрыть тонкости тестирования Doctrine в наших бандлах.