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…
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);
}
}
?>
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();
}
}
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);
}