Define Which Fixtures Have To Be Called In Tests

hello :)

I have plenty of fixtures in my appropriate folder however for each functional test I would like to call only useful fixtures for this specific test and not call all fixtures file present in folder. I tried to do it by created an init.php like it’s advised in guide but I don’t know how can I access to the $fixtures parameter array I defined in my test and in which there are all fixtures name that I need…

Have you an idea of how to manage it ?

I Think I succeeded to do it… I created a class MyDbFixtureManager and overrode the prepare function as :




Yii::import('system.test.CDbFixtureManager');


class MyDbFixtureManager extends CDbFixtureManager

{

  /**

	 * Prepares the fixtures for the whole test.

	 * This method is invoked in {@link init}. It executes the database init script

	 * if it exists. Otherwise, it will load all available fixtures.

	 */

	public function prepare()

	{

		$initFile=$this->basePath . DIRECTORY_SEPARATOR . $this->initScript;


		$this->checkIntegrity(false);

		if(is_file($initFile))

			require($initFile);

		else

		{

			foreach($this->getFixtures() as $tableName=>$fixturePath)

			{

        if(in_array($tableName,$this->fixtures)) { //KLUDGE

          $this->resetTable($tableName);

          $this->loadFixture($tableName);

        } //

			}

		}

		$this->checkIntegrity(true);

	}

}



then I change the call of the main fixture class in config/test.php. Moreover, here is my setUp() function in test/WebTestCase.php




	protected function setUp()

	{

		parent::setUp();

    //$this->setBrowser('*firefox');

    if(is_array($this->fixtures))

			$this->getFixtureManager()->load($this->fixtures);

		$this->setBrowserUrl(TEST_BASE_URL);

	}



With that, only fixtures which are defined in the $fixtures parameter of my test are called, and I save a lot of truncate/insert queries to my DB.

The thing is that I don’t know if I’m doing right… or if there is another way, indeed, althouth it doesn’t insert and truncate tables which are not defined in $fixtures, it runs query such as

[sql]

SELECT conname, consrc, contype, indkey FROM (

            SELECT


                    conname,


                    CASE WHEN contype='f' THEN


                            pg_catalog.pg_get_constraintdef(oid)

[…]

[/sql]

for all fixtures… which is a lot of useless request… I only need some table fixtures not all =(

Ok So… Apparently this is doing the job, I simply comment the resetTable() and loadFixture() function for all fixtures… Doing that, only fixtures defined in $fixtures parameter of your test are run.




<?php

Yii::import('system.test.CDbFixtureManager');


class MyDbFixtureManager extends CDbFixtureManager

{

  /**

	 * Prepares the fixtures for the whole test.

	 * This method is invoked in {@link init}. It executes the database init script

	 * if it exists. Otherwise, it will load all available fixtures.

	 */

	public function prepare()

	{

		$initFile=$this->basePath . DIRECTORY_SEPARATOR . $this->initScript;


		$this->checkIntegrity(false);

		if(is_file($initFile))

			require($initFile);

		/*else

		{

			foreach($this->getFixtures() as $tableName=>$fixturePath)

			{

        if(in_array($tableName,$this->fixtures)) { //KLUDGE

          $this->resetTable($tableName);

          $this->loadFixture($tableName);

        } //

			}

		}*/

		$this->checkIntegrity(true);

	}

}

?>



Finally get what I was looking for after 3 days :

I re-created all my tables with the parameter "DIFERRABLE" for all my constraints. Then I extend class CPgsqlSchema and override method checkIntegrity in new class you can put in components/ as :




public function checkIntegrity($check=true,$schema='')

        {

                $db = $this->getDbConnection();

                if ($check) {

                    $db->createCommand("SET CONSTRAINTS ALL DEFERRED")->execute();

                } else {

                    $db->createCommand("SET CONSTRAINTS ALL IMMEDIATE")->execute();

                }

        }



and add driverMap parameter in config/test.php :




'db' => array( // for fixtures

                    ...

                    'class' => 'system.db.CDbConnection',

                    'driverMap' => array('pgsql' => 'MyOverridePgsqlSchema'),



I had to change my setUp() function aswell in my WebTestCase for functional tests like :




	protected function setUp()

	{

    $transaction = Yii::app()->db->beginTransaction();

    try {

      parent::setUp();

      $transaction->commit();

    }

    catch (Exception $e) {

      $transaction->rollBack();

    }

    //$this->setBrowser('*firefox');

    $this->setBrowserUrl(TEST_BASE_URL);

	}



If you want to just reset tables, for a specific test, giving in your $fixtures parameter set in your test, rewrite your prepare() function of CDbFixtureManager as :




public function prepare()

	{

    $initFile=$this->basePath . DIRECTORY_SEPARATOR . $this->initScript;

    $this->checkIntegrity(false);

    if(is_file($initFile))

      require($initFile);

    /*else

    {

      foreach($this->getFixtures() as $tableName=>$fixturePath)

      {

        $this->resetTable($tableName);

        $this->loadFixture($tableName);

      }

    }*/

    $this->checkIntegrity(true);

	}