Setting up testing and fixtures in Symfony2 is vital if you plan on starting Test Driven Development or you simply want to start covering your code with properly written tests that can access mock data.
1. Install PHPUnit and php 5.6
The first thing you need to do is to install PHPUnit on your machine:
$ wget https://phar.phpunit.de/phpunit.phar $ chmod +x phpunit.phar $ sudo mv phpunit.phar /usr/local/bin/phpunit $ phpunit --version
and then, if needed, also upgrade your PHP version to 5.6:
$ sudo apt-get install language-pack-en-base $ export LC_CTYPE="en_US.UTF-8" $ sudo add-apt-repository ppa:ondrej/php5-5.6 $ sudo apt-get update $ sudo apt-get install php5
and make sure everything’s ok by running: phpunit -c app/
Please note that this is not a testing tutorial so if you’d like to learn more about how to actually test your Symfony2 app, then please read their documentation.
2. Setup and create a test database
In order to be able to configure testing and fixtures in a Symfony2 app a separate, independent database is needed so that your dev environment is not affected.
In the config_test.yml
file you simply need to add:
doctrine: dbal: host: 127.0.0.1 dbname: testdb user: [YOUR_MYSQL_USERNAME] password: [YOUR_MYSQL_PASSWORD]
then simply run php app/console doctrine:database:create --env=test
Related: Send Emails in Symfony2: The Right Way
3. Build the BaseTestSetup class
Once our test database is ready we can start building our BaseTestSetup
class, one which will serve as parent for all of our tests.
<?php namespace AppBundle\Tests; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; abstract class BaseTestSetup extends WebTestCase { protected $client; protected $container; protected $em; protected function setUp() { $this->client = static::createClient(); $this->container = $this->client->getContainer(); $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager(); } }
4. Install the LiipFunctionalTestBundle
Even though Symfony does have an out of the box solution to setup and test your app, the LiipFunctionalTestBundle provides base classes for functional tests to assist in setting up testing and fixtures and HTML5 validation.
After you install and configure the bundle, go back to your BaseTestSetup
class and make the necessary modifications:
<?php namespace AppBundle\Tests; use Doctrine\ORM\Tools\SchemaTool; use Liip\FunctionalTestBundle\Test\WebTestCase; abstract class BaseTestSetup extends WebTestCase { protected $client; protected $container; protected $em; protected function setUp() { $this->client = static::createClient(); $this->container = $this->client->getContainer(); $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager(); if (!isset($metadatas)) { $metadatas = $this->em->getMetadataFactory()->getAllMetadata(); } $schemaTool = new SchemaTool($this->em); $schemaTool->dropDatabase(); if (!empty($metadatas)) { $schemaTool->createSchema($metadatas); } $this->postFixtureSetup(); $this->loadFixtures(array( 'AppBundle\DataFixtures\ORM\LoadUserData', )); } }
The new code above simply drops and creates the database each them tests run. Then it loads the fixtures that you’ll need. The LoadUserData
class does not exist yet so we’ll go right ahead and add it by following the handy tutorial found on Symfony’s website.
5. Write the very first test
Now that have your fixtures ready, you can go ahead and write your first test. Create a new file in your AppBundle/Tests
folder called UserTest.php
, next to BaseTestSetup.php
:
<?php namespace AppBundle\Tests; use AppBundle\Tests\BaseTestSetup; class UserTest extends BaseTestSetup { public function testSuggestImprovementEmail() { // assuming that you named your user 'username' in your Fixtures $crawler = $this->client->request('GET', '/show/username'); $this->assertGreaterThan( 0, $crawler->filter('html:contains("Hello first user!")')->count() ); } }
And that’s about it! You now have everything you need to properly test your awesome app.
1 Comment
Comments are closed.
The only phar you should ever wget is composer.phar