Hola a todos:
Cuando leemos el manual de Symfony2, explica en el epígrafe “3.35.2 Probando la funcionalidad ” como acceder al núcleo del framework para ejecutar consultas reales en la base de datos y de esta forma poder hacer pruebas automáticas. El problema está que para poder hacer pruebas válidas necesitamos tener una base de datos llena con datos limpios y conocidos, que nos permita predecir el comportamiento y de esta manera poder crear las pruebas.
En symofny 1 cuando creabamos una prueba utilizando el método “loadData ” de la clase “sfDoctrineData(); ” logramos cargar datos limpios para nuestras pruebas. Lamentablemente por lo que se ve en la documentación no hay nada parecido a esto en Symfony2. Por lo tanto en la presente entrada de este blog les comento como implementar esta característica con Symfony2.
- Primero debemos tener instalado en nuestro proyecto el bundle “StofDoctrineExtensionsBundle” y crear los fixtures según la documentación de este bundle.
Configurar una conexión a la base de datos para el entorno de prueba. Debemos utilizar una base de datos distinta a la de desarrollo pues esta base de datos se va a cargar con datos nuevos cada vez que se haga una prueba que lo necesite.
# Doctrine Configuration, fichero config/config_test.yml doctrine: dbal: driver: %database_driver% host: %database_host% port: %database_port% dbname: base_datos_test #aquí se pone el nombre de la base de datos de prueba user: %database_user% password: %database_password% charset: UTF8 orm: auto_generate_proxy_classes: %kernel.debug% auto_mapping: true
Luego tenemos que crear la base de datos de prueba.
php app/console doctrine:database:create --env=test
Creamos la estructura de la base de datos.
php app/console doctrine:schema:create --env=test
Cada vez que se haga un cambio en el modelo de nuestro sistema, se creen nuevas tablas o se modifique alguna de las existentes, debemos ejectuar el siguiente comando para actualizar nuestra base de datos de prueba.
app/console doctrine:schema:update --env=test
Luego de esto lo que queda es crear las pruebas. Veamos el siguiente ejemplo.
Supongamos que tenemos una clase “User” y queremos comprobar es si la página de listado muestra de forma correcta todos los registros. Para esto tenemos creados unos fixtures que registra 3 usuarios en la base de datos. Supongamos que para ver el listado debemos acceder a la siguiente ruta “/users” y en esta página me genera una página html como esta.
<table class="user_list_test"> <tr> <td>usuario 1</td> </tr> <tr> <td>usuario 2</td> </tr> <tr> <td>usuario 3</td> </tr> </table>
A la tabla le ponemos como clase “user_list_test” para poder accederla desde nuestra prueba. Luego creamos una prueba con el siguiente código.
<?php namespace Acme\UserBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Bundle\DoctrineFixturesBundle\Common\DataFixtures\Loader as DataFixturesLoader; use Doctrine\Common\DataFixtures\Purger\ORMPurger; use Doctrine\Common\DataFixtures\Executor\ORMExecutor; class UserControllerTest extends WebTestCase { /** * @var \Doctrine\ORM\EntityManager */ private $em; private $container; private $current_kernel; public function setUp() { $kernel = static::createKernel(); $kernel->boot(); $this->current_kernel = $kernel; $this->container = $this->current_kernel->getContainer(); $this->em = $this->container->get('doctrine.orm.entity_manager'); } public function testLoadData() { $paths = array(); foreach ($this->current_kernel->getBundles() as $bundle) { $paths[] = $bundle->getPath().'/DataFixtures/ORM'; } $loader = new DataFixturesLoader($this->container); foreach ($paths as $path) { if (is_dir($path)) { $loader->loadFromDirectory($path); } } $fixtures = $loader->getFixtures(); if (!$fixtures) { throw new InvalidArgumentException( 'No hay fixtures para cargar' ); } $purger = new ORMPurger($this->em); $purger->setPurgeMode(ORMPurger::PURGE_MODE_TRUNCATE); $executor = new ORMExecutor($this->em, $purger); $executor->execute($fixtures); } /** * @depends testLoadData */ public function testIndex() { $client = static::createClient(); $crawler = $client->request('GET', '/users'); $this->assertTrue($crawler->filter('table.user_list_test tr')->count() == 3); } }
Acontinuación una explicación del código.
El método “setUp” se encarga de inicializar la conexión con la base de datos igual a como viene explicado en el epígrafe “3.35.2 Probando la funcionalidad ” del manual de Symfony.
El método “testLoadData” es el encargado de cargar los datos de los fixtures. Este método hace el mismo procedimiento que el comando “doctrine:fixtures:load” del bundle “StofDoctrineExtensionsBundle”.
El método “testIndex” es el que realmente hace la prueba, contando la cantidad de filas (tr) que tiene la tabla con class “user_list_test” que deben ser exactamente 3.
La anotación “@depends testLoadData” le indica a PHPUnit que antes de ejecutar la prueba “testIndex” primero debe ejecutar el métdo “testLoadData” que es el encargado de cargar los datos.
Como siempre expero que este artículo sea de su interés y espero comentarios.