3

I would like to append fixtures in my functional test (based on LiipFunctionalTestBundle in symfony 2.8. Even it is a dev database I working on, I do still need to append the fixtures since I will have:

  • regional data (country, region, county)
  • vehicule brands and models
  • ...

Consequently, having the DB purged after each functional test will not be nice for me.

NOTICE: Appending fixtures (without purging) through command line is working with success: php app/console doctrine:fixtures:load --append

So, below is my functional test:

<?php

namespace Minn\APIBundle\Tests\Controller;

use Liip\FunctionalTestBundle\Test\WebTestCase as WebTestCase;
//use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as WebTestCase;
use Minn\APIBundle\Tests\Fixtures\Entity\LoadBrandData;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;

class BrandControllerTest extends WebTestCase {

    public function setUp() {
        $this->auth = array(
            'PHP_AUTH_USER' => 'restapi',
            'PHP_AUTH_PW' => 'secretpw',
        );

        $this->client = static::createClient(array(), $this->auth);
    }

    public function testJsonGetPageAction() {
        $fixtures = array('Minn\APIBundle\Tests\Fixtures\Entity\LoadBrandData');
        $this->loadFixtures($fixtures);
        $brands = LoadBrandData::$brands;
        $brand = array_pop($brands);

        $route = $this->getUrl('api_1_brand_get_brand', array('id' => $brand->getId(), '_format' => 'json'));

        $this->client->request('GET', $route, array('ACCEPT' => 'application/json'));
        $response = $this->client->getResponse();
        $this->assertJsonResponse($response, 200);
        $content = $response->getContent();

        $decoded = json_decode($content, true);
        $this->assertTrue(isset($decoded['id']));
    }

    // ..
}

This test purges the DB. So, I tried the code proposed in link by doing this change:

// removed code
$fixtures = array('Minn\APIBundle\Tests\Fixtures\Entity\LoadBrandData');
$this->loadFixtures($fixtures);

// new code
$this->runCommand('doctrine:fixtures:load --append --no-interaction --fixtures=src/Minn/APIBundle/Tests/Fixtures/Entity/LoadBrandData.php');

But, functional test doest not work.

There was 1 error:

1) Minn\APIBundle\Tests\Controller\BrandControllerTest::testJsonGetPageAction
Error: Call to a member function getId() on null

/home/amine/NetBeansProjects/minnapi/src/Minn/APIBundle/Tests/Controller/BrandControllerTest.php:27

I tried to used options available in the function loadFixtures() by doing this change:

// removed code:
$fixtures = array('Minn\APIBundle\Tests\Fixtures\Entity\LoadBrandData');
$this->loadFixtures($fixtures);

// new code 
$fixtures = array('Minn\APIBundle\Tests\Fixtures\Entity\LoadBrandData');
$this->loadFixtures($fixtures, null,'doctrine', ORMPurger::PURGE_MODE_DELETE);

Verdict: DB is always purged after each run of the functional test.

So, any suggestions??

Thanks,

NB: bundles versions described in composer.json

    "doctrine/doctrine-fixtures-bundle": "dev-master",
    "phpunit/phpunit": "5.4.*",
    "liip/functional-test-bundle":"1.6.*",
    "guzzle/guzzle": "v3.9.*"
Community
  • 1
  • 1
Amine Jallouli
  • 3,919
  • 8
  • 36
  • 73
  • Is there some reason for not using a separate database for functional testing as would otherwise be expected? – geoB Jun 21 '16 at 14:51
  • I am open to all ideas. You have a link or an example ? – Amine Jallouli Jun 21 '16 at 15:00
  • Do you use the SQLite database as described in the bundle's configuration? – A.L Jun 21 '16 at 15:10
  • I use mysql. That's it. No sqlite – Amine Jallouli Jun 21 '16 at 16:26
  • If for some reason SQLite is not an option (for example, when you use a MySQL function that is not available in SQLite) you can always define a separate MySQL database for the test environment. As for appending fixtures, use `...DataFixtures\ORM` for your dev environment, `..DataFixtures\Test` for the test environment. – geoB Jun 21 '16 at 17:35
  • Can you be more explicite @geoB regarding the dev environment and test environment? – Amine Jallouli Jun 22 '16 at 14:01
  • You comment is right! I do use geospatial queries and I guess they will not work in SQLite. – Amine Jallouli Jun 22 '16 at 14:05

2 Answers2

2

The only solution to avoid having the database purged is to create a testing database. To do that, below are the steps:

config of a testing database

# the config has to be done in config_test.yml
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   pdo_mysql
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   test
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8

creation of the database and the tables

// this command is run only once (just for creating the testing db)
$ php app/console doctrine:database:create --env=test
// this command is needed when you have new entities
$ php app/console doctrine:schema:create --env=test

How to load fixtures in the test?

    $fixtures = array('Minn\APIBundle\Tests\Fixtures\Entity\LoadBrandData');
    $this->loadFixtures($fixtures);
    $brands = LoadBrandData::$brands;

Hope it will help others!

Amine Jallouli
  • 3,919
  • 8
  • 36
  • 73
0

It is possible to use a SQLite database for functional testing. See the docs for details on the bundle's configuration. If, for example, you are using MySQL it is pretty straightforward to create a database in the test environment with

$ php app/console doctrine:database:create --env=test
$ php app/console doctrine:schema:create --env=test

and have the same behavior in the test environment as in the dev environment.

Your fixtures should load readily.

Edit: in config_test.yml:

doctrine:
    dbal:
        driver:   pdo_mysql
        host:     localhost
        port:     3306
        dbname:   minnapi_test
        user:     "%database_user%"
        password: "%database_password%"

Copy .../web/app_dev.php to .../web/app_test.php and modify one line to read $kernel = new AppKernel('test', true);

geoB
  • 4,578
  • 5
  • 37
  • 70
  • I can not your use your solution since the database already exists in mySQL: `SQLSTATE[HY000]: General error: 1007 Can't create database 'minnapi'; database exists` – Amine Jallouli Jun 24 '16 at 09:05