Setting up Symfony2 for Testing


Setting a Symfony2 project up for testing can be tricky, however in this short guide I will show you how you are able to setup your project so you can spend more time coding and less time trying to fix issues you run into while setting up a testing environment.

One of the first steps you will need to do is setup your test environment in symfony2. The way we are going to setup the environment is to use Doctrine ORM and configure it to use SQLite for the database.

Start by adding a few lines to some of the configuration files.

# app/config/parameters.yml
parameters:
    database_driver: pdo_sqlite
    database_path:   "%kernel.root_dir%/data.db3"

This tells Doctrine to use SQLite and where it can find the database file.

# app/config/config_test.yml
doctrine:
    dbal:
        path: "%database_path%"

You shouldn’t need to add anything else to the config_test.yml file since it will import other configuration files which will be used to configure the rest of doctrine. You can check your configuration by running app/console debug:config doctrine --env=test and making sure everything looks as expected.

At this point running phpunit -c app will fail. There are just a few more steps we need to complete before everything will work together.

Now we need to create a testing bootstrap file that PHPUnit will use, and then update the phpunit.xml.dist file.

<?php
// app/test.bootstrap.php

passthru(sprintf('php "%s/console" cache:clear --env=test --no-warmup --no-interaction', __DIR__));
passthru(sprintf('php "%s/console" doctrine:database:drop --env=test --force --no-interaction', __DIR__));
passthru(sprintf('php "%s/console" doctrine:database:create --env=test --no-interaction', __DIR__));
passthru(sprintf('php "%s/console" doctrine:schema:update --force --env=test --no-interaction', __DIR__));
// Fails since using SQLite =(
//passthru(sprintf('php "%s/console" doctrine:migrations:migrate --env=test --no-interaction', __DIR__));

$fixtures = array(
    'src/AppBundle/Tests/DataFixtures/currencies.yml',
);
foreach ($fixtures as $fixture) {
    passthru(sprintf('php "%s/console" h4cc_alice_fixtures:load:files -vvv --env=test --no-interaction %s', __DIR__, $fixture));
}

require __DIR__.'/bootstrap.php.cache';

But what if you have some fixtures you want to load? If you are using the bundle for doctrine fixtures or any other bundle to load fixtures, you just need to add some more code after you create and setup the database.

<?php

// setup database

$fixtures = array(
    'src/AppBundle/Tests/DataFixtures/filename.yml',
);
foreach ($fixtures as $fixture) {
    passthru(sprintf('php "%s/console" h4cc_alice_fixtures:load:files -vvv --env=test --no-interaction %s', __DIR__, $fixture));
}
// OR
passthru(sprintf('php "%s/console" doctrine:fixtures:load -vvv --env=test --no-interaction', __DIR__));

// require bootstrap file

Next just edit app/phpunit.xml.dist and modify or add the bootstrap attribute to use test.bootstrap.php instead of bootstrap.php.cache and now you can run phpunit -c app/ and have a complete database setup with fixtures and all!