0

Hope Everyone is doing great.

I have a problem. I need to get my fixtures loaded in db before running acceptance test in codception in my Yii2 Application. here is teh detail for it.

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:

common\modules\myCustomModule\tests\acceptance\models\DashboardCest ```

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 common\modules\myCustomModule\tests\fixtures\CountryFixture

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: common\modules\myCustomModule\tests\data\country_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,
    ],
];

for just in case you need my configurations: common\modules\myCustomModule\tests\acceptance.suite.yml

class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver
        - Yii2:
           part:
              [init, orm, fixtures]
    config:
        db:
          populate: false
          cleanup: false

        WebDriver:
            url: 'http://localhost/myProject/'
            browser: phantomjs
            window_size: 1920x1310
            capabilities:
              webStorageEnabled: true

Codeception: 2.2.9 Yii2 application version: 2.0.12 composer: 1.4.2 Also I am using PhantomJs for testing

Please let me know of any questions. Stay Blessed.

ahmednawazbutt
  • 823
  • 12
  • 34
  • To get through other ways, I tried directly loading fixtures using http://www.yiiframework.com/doc-2.0/guide-test-fixtures.html#loading-fixtures but still got nothing. I started a thread at github and till now, its of no help https://github.com/Codeception/Codeception/issues/4099 – ahmednawazbutt Aug 25 '17 at 13:37
  • The framework specific modules are for use with Functional testing, not Acceptance testing – sunomad Aug 25 '17 at 15:08
  • I want to test my webpages. For that I need to write acceptance testing – ahmednawazbutt Aug 26 '17 at 20:36
  • But then you cannot use that module for loading fixtures. You will have to find another way to update the database. Codeception provides the ability to restore the complete database with a dump. If you want more control you can write your own sql insert or update queries and run them with the function I posted here: https://stackoverflow.com/questions/44499975/codeception-acceptance-tests-within-database-transaction-on-mysql/44504577#44504577 – sunomad Aug 27 '17 at 17:17

1 Answers1

0

Well I figured out a solution based on a thread I started at https://github.com/Codeception/Codeception/issues/4099

I simply loaded fixtures in my acceptance test just like I do in mu unit tests

here is the method I placed inside my Cest file before _before() method

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'
        ],
    ];
}

Funny thing is I cannot see the fixtures getting loading in my database but what I can do here is check in my cest file to know if data is stored in db before running my test methods.

I placed this code in my _before() method

    $I->seeRecord(UserModel::className(), ['username'=>'admin', 'email'=>'admin@offneo.com']);
    $I->seeRecord(CountryModel::className(), ['name'=>'Pakistan', 'iso'=>'PK']);
    $I->seeRecord(ResumeModel::className(), ['title'=>'Second Resume', 'created_at'=>'2017-08-15 10:06:06']);

the above lines confirm me that fixtures are loaded in my db. Now I can place the rest of code for my acceptance test as I please.

May be this would help someone. Stay Blessed.

ahmednawazbutt
  • 823
  • 12
  • 34
  • This was answered long ago but an addendum why you can't see them in the database: The yii2 module for codeception does everything in a transaction by default, so nothing is actually committed to the database. You can disable this by setting `modules.config.Yii2.transaction` to `false` in your codeception.yml – DBX12 Jan 13 '22 at 07:08