Tests and fixtures

Hi

I have 3 question about tests and fixtures.

  1. I save fixtures in tests/codeception/common/fixtures and tests/codeception/common/unit/fixtures I think in common/fixtures I must put "global fixtures" and in common/unit/fixtures I must put fixtures, which use in common/unit tests. Is it true? But where I must put fixtures for functional and accept test? In their directory is not fixture directory…

  2. When I use command


./yii fixture User

it find fixture in tests/codeception/common/unit/test. Why? I think for more logic, it must finds fixtures in "global fixtures directory" Am I wrong?

  1. Why does yii not unload fixtures after test? I use related fixtures (and tables)(GoogleKeywordFixture -> GoogleGroupFixture) in first test. In second I use only GoogleGroupFixture. In second test yii try reload(unloadFixtures(‘GoogleKeywordFixture’), loadFixtures(‘GoogleKeywordFixture’)) , but it finished with error, because GoogleKeywordFixture referrers to GoogleKeywordFixture(from prev test). How to resolve this problem?

Sorry for my english.

Thanks.

  1. I believe this is correct though the semantic for "global fixtures" means fixtures that need to be loaded before any others. Such as the initDb fixture. I prefer to call fixtures that can be used across different test suits "general purpose fixtures" to avoid ambiguity.

  2. This might be because unit is the default namespace for the fixture. You can specify a different namespace with

–namespace=‘tests\codeception\common\fixtures’ (for example)

It is worth noting you can also specify "global fixtures" (that run before anything else) via –globalFixtures

  1. We will need a bit more information (and to see your code) to help you here.

Thanks.

I have two tables(and Models). GoogleGroup(id, name) and BadKeyword(id, name, group_id). Field BadKeyword.group_id - foreign key to GoogleGroup.id.

When I have created BadKeywordFixtures I set depends




class BadKeywordsFixture extends ActiveFixture

{

    public $depends = [

        'tests\codeception\common\fixtures\GoogleGroupsFixture',

    ];


    public $modelClass = 'common\modules\bidmanager\models\costnoatification\BadKeywords';


    public $dataFile = '@tests/codeception/common/fixtures/data/init_bad_keywords.php';


}



I have two tests. First test use GoogleGroupFixtures and BadKeywordFixtures.Second test use only GoogleGroupFixtures

First test:




class BadKeywordsTest extends DbTestCase

{

.........

public function fixtures()

    {

        return [

            'groups' => [

                'class' =>  GoogleGroupsFixture::className(),

            ],

            'badKeywords' => [

                'class' =>  BadKeywordsFixture::className(),

            ],

            'campaigns' => [

                'class' =>  GoogleCampaignsFixture::className(),

            ],

          

        ];

    }


.......

}



Second test:




class KeywordsTest extends TestCase

{

.......

public function fixtures()

    {

        return [

            'groups' => [

                'class' =>  GoogleGroupsFixture::className(),

            ],

            'keywordScopes' => [

                'class' =>  KeywordScopesFixture::className(),

            ],

        ];

    }

......

}



When I run


codeception run

in tests/codeception/common/

I get this error:


---------

1) tests\codeception\common\unit\models\GoogleKeywordsTest::testSavingMatchType

yii\db\IntegrityException: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`yii2_advanced_tests`.`bad_keywords`, CONSTRAINT `bad_keywords_group_id_keywords_google_group_fk` FOREIGN KEY (`group_id`) REFERENCES `pdf_nautilius`.`google_groups` (`id`))

The SQL being executed was: DELETE FROM `pdf_nautilius`.`google_groups`




I’m willing to bet your issue is because you have integrity constraints on your database (such as using innoDb tables with foreign keys in MYSQL). The tables need to be dropped in a specific order and yii is failing to do so.

Yii2 provides a global initDbFixture to solve this specific issue. You can read more about it here : https://github.com/yiisoft/yii2/blob/master/docs/guide/test-fixtures.md#defining-and-using-global-fixtures

You are extending DbTestCase which means it should work, which I find odd… maybe try adding the fixture to the globalFixtures() method of your Test class to see if that works.

Is there perhaps a pivot table that needs to be dropped as well? And that yii wouldn’t find from your fixture/AR definitions ?

Also:

Because BadKeywordsFixture depends on GoogleGroupsFixture you don’t have to define the groups fixture in your test class. It doesn’t hurt to have it there as Yii2 handles the fact that it’s a dependency of BadKeywords but it isn’t necessary:


class BadKeywordsTest extends DbTestCase

{

.........

public function fixtures()

    {

        return [

            'badKeywords' => [

                'class' =>  BadKeywordsFixture::className(),

            ],

            'campaigns' => [

                'class' =>  GoogleCampaignsFixture::className(),

            ],

          

        ];

    }


.......

}

Thanks, I know it.

Hm… How can I use "this" global fixtures in my case? I know about it, but how it use for one TestCase?

I add it in globalFixtures, but it is not woking. In parent class methods globalFixtures() and fixtures() are merging. https://github.com/yiisoft/yii2/blob/master/framework/test/FixtureTrait.php#L146

Thanks.