Codeception: Load fixtures in acceptance testing - codeception

Created on 3 Apr 2017  路  8Comments  路  Source: Codeception/Codeception

Target:
Load fixtures in database so that I can run acceptance tests on them.

Problem:
Despite of my a at most efforts, I am still I am unable to achieve this affect

Here is the data that I got to share with you:

namespace: commonmodulesmyCustomModuletestsacceptancemodelsDashboardCest

class ResumeDashboardCest
{
    public function _before(AcceptanceTester $I)
    {
        $I->haveFixtures([
            'country' => [
                'class' => CountryFixture::className(),
                'dataFile' => codecept_data_dir() . 'country_data.php',
            ],
            'region' => [
                'class' => RegionFixture::className(),
                'dataFile' => codecept_data_dir() . 'region_data.php',
            ],
            'city' => [
                'class' => CityFixture::className(),
                'dataFile' => codecept_data_dir() . 'city_data.php',
            ],
            'user_group' => [
                'class' => UserGroupFixture::className(),
                'dataFile' => codecept_data_dir() . 'user_group.php',
            ],
            'user' => [
                'class' => UserFixture::className(),
                'dataFile' => codecept_data_dir() . 'user.php',
            ],
            'status' => [
                'class' => StatusFixture::className(),
                'dataFile' => codecept_data_dir() . 'status_data.php',
            ],
            'resume' => [
                'class' => ResumeFixture::className(),
                'dataFile' => codecept_data_dir() . 'resume_data.php'
            ],
        ]);
        //    initialize the module first

        // fill in the login page before performing my main test
        $I->amGoingTo("Login in My Application");

        $I->amOnPage(Url::toRoute('/site/login'));
        $I->fillField('#loginform-username', 'admin');
        $I->fillField('#loginform-password', 'gulabmehak');

        $I->click('.btn-success'); // The login button
        $I->wait(3);    //  wait for 3 seconds meanwhile bakend processing is complete
        $I->dontSee('Incorrect username or password.');
    }

    // my test function
    public function load_HomePage(AcceptanceTester $I)
    {
        $I->amOnPage( Url::toRoute('/'.\Yii::$app->params['ModuleName'].'/resume/index') );

        $I->see(T::t('main', 'My Resumes'));
        $I->see(T::t('main', 'My Resumes'), 'ul.breadcrumb li.active');
    }
}

Here is the fixture for country
namespace: commonmodulesmyCustomModuletestsfixturesCountryFixture

class CountryFixture extends \yii\test\ActiveFixture
{
    public $modelClass = 'common\modules\location\models\Country';    // the model for this belongs to another module

    public function beforeLoad() {
        parent::beforeLoad();
        $this->db->createCommand()->setSql('SET FOREIGN_KEY_CHECKS = 0')->execute();
    }

    public function afterLoad() {
        parent::afterLoad();
        $this->db->createCommand()->setSql('SET FOREIGN_KEY_CHECKS = 1')->execute();
    }
}

same goes for the rest of fixture files but I've eliminated them for ease.

Here is the data (fixture data) file:
location: commonmodulesmyCustomModuletestsdatacountry_data.php

<?php
return [
    [
        'name' => 'Pakistan',
        'iso' => 'PK',
        'status' => 1,
    ],
    [
        'name' => 'China',
        'iso' => 'CH',
        'status' => 1,
    ],
    [
        'name' => 'United States of America',
        'iso' => 'US',
        'status' => 1,
    ],
    [
        'name' => 'Saudi Arabia',
        'iso' => 'SA',
        'status' => 1,
    ],
    [
        'name' => 'Japan',
        'iso' => 'JP',
        'status' => 1,
    ],
];

Here is my configuration info:

Codeception: 2.2.9
Yii2 application version: 2.0.12
composer: 1.4.2

Yii

Most helpful comment

All 8 comments

@ahmednawazbutt Try to create your test as cest-file so you could use _before method of your Cest class where you can load fixtures the same way as you do it in unit tests.

See http://codeception.com/docs/07-AdvancedUsage#cest-classes

Thank you for your response @kuntashov! I have tried this too but still am unable to load fixtures. I also have seen the link you share a number of times. Following that as well gives nothing at all. Can you please suggest some working program example please.
Here is my class
````bash
class CategoryCest
{
public function _before(AcceptanceTester $I)
{
Yii::$app->getModule('modulename')->init(); //works fine

    self::accountLogin($I); //  Not providing username and password means I am going to log in as an Admin
}

 public function CategoryIndex(AcceptanceTester $I)
{
    $I->wantTo('Try to reach on Category Home page even If I am not authorized. . .');
    //  perform some activities and actions
}

}
````
Any help is appreciated.
Thanks in advance.

@samdark @DavertMik This is Yii specific, do you know what is the issue here?

I just need to load fixtures in my acceptance tests before running them.
just like we do in unit testing. (we refresh the db table with fixture values and then run test upon them afterwards

@kuntashov, @Naktibalda any solution yet????
even if this is not possible, I'll just settle down for keeping my unit test values still in db so that I could run my acceptance tests. but then I need db to be cleaned first each time I run my unit tests

@ahmednawazbutt I have no idea what you are doing here.

@samdark It seems to be a Yii question, please try to help.

@samdark Thank you very much for your answer.
The solution you just provided is awesome.

just one small wrinkle, I still could not see anything in my db on my own so I wrote a small piece of code to see if the fixtures data got loaded in db or not

Here is what I did (starting from your solution)

class ResumeDashboardCest
{
    public function _fixtures()
    {
        return [
            'country' => [
                'class' => CountryFixture::className(),
                'dataFile' => codecept_data_dir() . 'country_data.php',
            ],
            'region' => [
                'class' => RegionFixture::className(),
                'dataFile' => codecept_data_dir() . 'region_data.php',
            ],
            'city' => [
                'class' => CityFixture::className(),
                'dataFile' => codecept_data_dir() . 'city_data.php',
            ],
            'user_group' => [
                'class' => UserGroupFixture::className(),
                'dataFile' => codecept_data_dir() . 'user_group.php',
            ],
            'user' => [
                'class' => UserFixture::className(),
                'dataFile' => codecept_data_dir() . 'user.php',
            ],
            'status' => [
                'class' => StatusFixture::className(),
                'dataFile' => codecept_data_dir() . 'status_data.php',
            ],
            'resume' => [
                'class' => ResumeFixture::className(),
                'dataFile' => codecept_data_dir() . 'resume_data.php'
            ],
        ];
    }

    public function _before(AcceptanceTester $I)
    {
                //  Check the content of fixtures in db
        $I->seeRecord(User::className(), ['username'=>'admin', 'email'=>'[email protected]']);
        $I->seeRecord(OlocationCountry::className(), ['name'=>'Pakistan', 'iso'=>'PK']);
        $I->seeRecord(OresumeResume::className(), ['title'=>'Second Resume', 'created_at'=>'2017-08-15 10:06:06']);
    }
}

After that my test methods that I am supposed to write e.g.
````
public function ResumeDashboard(AcceptanceTester $I)
{
$url = Url::toRoute(["My Route to my Action"]);
$I->amOnPage( $url );

    $I->see(some text in my page);
}

````

Sorry to copy your solution. Just did this so that someone who needs this would get all-in-one-solution.

Was this page helpful?
0 / 5 - 0 ratings