Permalink
Browse files

Introduce testing recipe for Symfony2

  • Loading branch information...
1 parent 94fb0b2 commit f4a97b94e4c0bb2dcbf050678b5475a60566be98 @willdurand willdurand committed Aug 2, 2012
Showing with 164 additions and 0 deletions.
  1. +2 −0 cookbook/index.markdown
  2. +2 −0 cookbook/symfony2/index.markdown
  3. +159 −0 cookbook/symfony2/testing.markdown
  4. +1 −0 documentation/index.markdown
View
2 cookbook/index.markdown
@@ -62,6 +62,8 @@ title: The Cookbook
* [Adding A New Behavior In Symfony2](symfony2/adding-a-new-behavior-in-symfony2.html)
+* [Testing](symfony2/testing.html)
+
### Working with Silex ###
View
2 cookbook/symfony2/index.markdown
@@ -14,3 +14,5 @@ title: Working With Symfony2
* [The Symfony2 Security Component And Propel](the-symfony2-security-component-and-propel.html)
* [Adding A New Behavior In Symfony2](adding-a-new-behavior-in-symfony2.html)
+
+* [Testing](testing.html)
View
159 cookbook/symfony2/testing.markdown
@@ -0,0 +1,159 @@
+---
+layout: documentation
+title: Testing
+---
+
+# Testing #
+
+To build better and more reliable applications, you should test your code using
+both functional and unit tests. First, read the [Testing chapter](
+http://symfony.com/doc/current/book/testing.html) on the Symfony2 documentation.
+It explains everything you need to know to write tests for your Symfony2
+application. However, it doesn't explain how to configure Propel, or how to use
+it in your test classes.
+
+This recipe introduces Propel in the wonderful testing world.
+If you are reading it, you are probably interested in **functional tests** as
+relying on a database means you write functional tests, not unit tests.
+
+Symfony2 provides a
+[WebTestCase](https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php)
+which provides great features for your functional test classes. This is the
+class you need when you want to do black box testing. Then again, this is
+explained in the [Testing chapter - Functional
+tests](http://symfony.com/doc/current/book/testing.html#functional-tests).
+Moreover, Symfony2 comes with multiple environments, like **dev**, **prod** but
+also **test**. The Symfony2 Client, detailled in the section [Working with the
+Test Client](http://symfony.com/doc/current/book/testing.html#working-with-the-test-client)
+in the Symfony2 documentation, relies on this **test** environment.
+
+
+## The `test` Environment ##
+
+The `config_test.yml` file is where you have to put specific configuration for
+testing purpose. For example, you can setup a new database for your tests like
+`yourdatabase_test`:
+
+{% highlight yaml %}
+# app/config/config_test.yml
+propel:
+ dbal:
+ dsn: %database_driver%:host=%database_host%;dbname=%database_name%_test;charset=UTF8
+{% endhighlight %}
+
+You can also configure a `SQLite` connection instead of your production database
+vendor (`MySQL`, `PostgreSQL`, etc.). It's a good idea to use a different
+database vendor to ensure your application is not tied to a specific database,
+however sometimes it's not possible.
+
+As you may know, Propel uses smart code generation depending on the database
+vendor, and so on. You need to build both SQL and PHP code before to run your
+tests. It's doable by running a single command line, but it's not optimal.
+
+
+## The Propel WebTestCase ##
+
+A good idea is to extend the `WebTestCase` class in your application, and to add
+a few methods to run commands for you:
+
+{% highlight php %}
+<?php
+
+namespace Acme\DemoBundle\Tests\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase;
+
+class WebTestCase extends BaseWebTestCase
+{
+ private static $application;
+
+ public static function setUpBeforeClass()
+ {
+ \Propel::disableInstancePooling();
+
+ self::runCommand('propel:build --insert-sql');
+ }
+
+ protected static function getApplication()
+ {
+ if (null === self::$application) {
+ $client = static::createClient();
+
+ self::$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($client->getKernel());
+ self::$application->setAutoExit(false);
+ }
+
+ return self::$application;
+ }
+
+ protected static function runCommand($command)
+ {
+ $command = sprintf('%s --quiet', $command);
+
+ return self::getApplication()->run(new \Symfony\Component\Console\Input\StringInput($command));
+ }
+}
+{% endhighlight %}
+
+Basically, for each test class, it will build everthing before to execute test
+methods. By using this class, you just need to run `phpunit` in your project to
+run all tests, including functional tests that rely on a database.
+
+You can run more commands, like the `propel:fixtures:load` command. It's up to
+you. You now have all keys to automatically run functional tests with Propel
+inside.
+
+If you want to write unit tests for your Model classes for some reasons, you can
+follow the same principle in your own `TestCase` class.
+
+
+## The Propel TestCase ##
+
+If you don't use the Symfony2 Client, you don't need to extend the `WebTestCase`
+class, just write your own `TestCase` class:
+
+{% highlight php %}
+<?php
+
+namespace Acme\DemoBundle\Tests;
+
+require_once __DIR__ . '/../../../../app/AppKernel.php';
+
+class TestCase extends \PHPUnit_Framework_TestCase
+{
+ private static $application;
+
+ public static function setUpBeforeClass()
+ {
+ parent::setUpBeforeClass();
+
+ if (null === self::$application) {
+ self::runCommand('propel:build --insert-sql');
+ FixturesLoader::load();
+ }
+ }
+
+ protected static function getApplication()
+ {
+ if (null === self::$application) {
+ $kernel = new \AppKernel('test', true);
+ $kernel->boot();
+
+ self::$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
+ self::$application->setAutoExit(false);
+ }
+
+ return self::$application;
+ }
+
+ protected static function runCommand($command)
+ {
+ $command = sprintf('%s --quiet', $command);
+
+ return self::getApplication()->run(new \Symfony\Component\Console\Input\StringInput($command));
+ }
+}
+{% endhighlight %}
+
+Having both `WebTestCase` and `TestCase` classes allow you to write Propel aware
+tests in your application. You don't need anything else.
View
1 documentation/index.markdown
@@ -87,6 +87,7 @@ You can also look at [user contributed behaviors](../cookbook/user-contributed-b
* [Mastering Symfony2 Forms With Propel](../cookbook/symfony2/mastering-symfony2-forms-with-propel.html)
* [The Symfony2 Security Component And Propel](../cookbook/symfony2/the-symfony2-security-component-and-propel.html)
* [Adding A New Behavior In Symfony2](../cookbook/symfony2/adding-a-new-behavior-in-symfony2.html)
+* [Testing](../cookbook/symfony2/testing.html)
### Working with Silex ###

0 comments on commit f4a97b9

Please sign in to comment.