Functional tests inside a standalone Symfony2's bundle
Here is my own solution (I summarize all the process for testing in a standalone bundle):
1. First, a good bundle has its own composer.json
to define its dependencies:
{ "name": "my/own-bundle", "type": "symfony-bundle", "description": "Symfony2 bundle that provides ...", "keywords": ["my","own"], "license": "MIT", "authors": [ { "name": "John Doe", "email": "john.doe@omg.wtf" } ], "require": { "php": ">=5.3.2", "symfony/framework-bundle": ">=2.3" }, "require-dev": { "phpunit/phpunit": "3.7.*" }, "autoload": { "psr-0": { "My\\OwnBundle": "" } }, "target-dir": "My/OwnBundle", "minimum-stability": "dev"}
Note the use of the dependency on symfony/framework-bundle
which is needed for our tests on services. You certainly can lower the dependencies in specifying your own real dependencies on the symfony core.
With this file I can process the command (do it) to build the vendor directory of my bundle:
$ composer update
2. Then, I set my phpunit config file:
<!-- phpunit.xml.dist --><?xml version="1.0" encoding="UTF-8"?><phpunit backupGlobals="false" backupStaticAttributes="false" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" syntaxCheck="false" bootstrap="Tests/bootstrap.php"> <testsuites> <testsuite name="MyOwnBundle Test Suite"> <directory>./Tests/</directory> </testsuite> </testsuites> <filter> <whitelist> <directory>./</directory> <exclude> <directory>./Resources</directory> <directory>./Tests</directory> <directory>./vendor</directory> </exclude> </whitelist> </filter></phpunit>
3. Then, I set the php bootstrap for the autoload of the class in my test directory:
// Tests/bootstrap.php$file = __DIR__.'/../vendor/autoload.php';if (!file_exists($file)){ $file = __DIR__.'/../../../../../../vendor/autoload.php'; if (!file_exists($file)) throw new RuntimeException('Install dependencies to run test suite.');}$autoload = require_once $file;
These steps are standard for any test in a standalone bundle.
4. Now, I want to simulate an application to make some functionnal tests on my services:
I need a kernel class:
// Tests/AppKernel.php (you can define it in a subdirectory /Fixtures if you prefer)use Symfony\Component\HttpKernel\Kernel;use Symfony\Component\Config\Loader\LoaderInterface;class AppKernel extends Kernel{ public function registerBundles() { $bundles = array(); if (in_array($this->getEnvironment(), array('test'))) { $bundles[] = new Symfony\Bundle\FrameworkBundle\FrameworkBundle(); $bundles[] = new My\OwnBundle\MyOwnBundle(); } return $bundles; } public function registerContainerConfiguration(LoaderInterface $loader) { $loader->load(__DIR__.'/config.yml'); }}
And the corresponding config.yml
:
# Tests/config.ymlframework: secret: test session: storage_id: session.storage.mock_filemy_own: test: 2
Here is an example with a mock for the session. Don't forget to specify the correct framework configuration nodes if you want to have access to some services (if you don't specify the node session
, you have no service session
for instance).
5. Finally, I can retrieve my services like the following in my test classes:
// Tests/Functional/Handling/Handler.phpnamespace My\OwnBundle\Tests\Functional\Handling;use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;class HandlerTest extends WebTestCase{ private $handler; protected function setUp() { require_once __DIR__.'/../../AppKernel.php'; $kernel = new \AppKernel('test', true); $kernel->boot(); $container = $kernel->getContainer(); $this->handler = $container->get('my_own.handling.handler'); } public function testHandle() { $this->assert($this->handler->handle()); }}