How to use functions from models on test database in selenium tests

Hi guys,

I’m just writing some selenium tests for a website. Some actions create entrys in the database which I would like to retrieve, to test if everything works out like I want it.

The functions I need to read the values from database already exist - so I dont have to write them just for the tests ;-). - so don’t worry about that.

My test looks as follows at the moment:


$visitorsWithPassion = Statistic::getCountVisitorsWithPassion();

$this->click('s3b1');

$this->waitForVisible('start22');

$this->assertVisible('start22');

$visitorsWithPassionNew = Statistic::getCountVisitorsWithPassion() - 1;

$this->assertTrue($visitorsWithPassionNew === $visitorsWithPassion);

what I’m doing here is testing a javascript based website which fades div boxes in and out like a presentation …

The problem I finally have is, that if i call the function:


Statistic::getCountVisitorsWithPassion()

it leads to the dev database and not the test database. Does there exist a way to use the test database for these functions?

… would be awesome!

Thanks in advance,

Mayjestic

Lol, ok … seems that it already uses the test database for retrieving the datasets from the database …

The problem is, that it creates the database entry in the "dev" database instead of the "test" database (the user interaction leads to the "actionCreate", which points to the "dev" database instead of the "test" database)

–> how can I make it write to the "test" database should be the correct question.

Your test entry point (index-test.php) needs to use a test config, like this:

protected/config/test.php:


return CMap::mergeArray(

	require(dirname(__FILE__).'/local.php'),

	array(

		'components'=>array(

			'fixture'=>array(

				'class'=>'system.test.CDbFixtureManager',

			),

			'db'=>array(

				'connectionString' => 'mysql:host=localhost;dbname=test_database',

				'emulatePrepare' => true,

				'username' => 'admin',

							'tablePrefix' => 'test_',

				'password' => 'admin',

				'charset' => 'utf8',

			),

		),

	)

);

That’s what I do, or rather: did. I haven’t used testing for a while.

Thanks for your reply, but that’s what I actualy do right now. Like i sayed, when I call a function in a model from a selenium test file it uses the test database. But when I call a website (with index-test.php instead of index.php) it seems to always use the “dev” database.

Weird …

My test.php looks as follows:


return CMap::mergeArray(

        require(dirname(__FILE__) . '/main.php'),

        array(

            'components' => array(

                'fixture' => array(

                    'class' => 'system.test.CDbFixtureManager',

                ),

                /* uncomment the following to provide test database connection

                  'db'=>array(

                  'connectionString'=>'DSN for test database',

                  ),

                 */

                'db' => array(

                    'connectionString' => 'mysql:host=127.0.0.1;dbname=startregie_test',

                    'emulatePrepare' => true,

                    'username' => 'root',

                    'password' => '',

                    'charset' => 'utf8',

                    /*'tablePrefix' => 'tbl_',*/

                ),

            ),

        )

);

And my index-test.php:


// change the following paths if necessary

$yii=dirname(__FILE__).'/../Yii/framework/yii.php';

$config=dirname(__FILE__).'/protected/config/test.php';


// remove the following line when in production mode

defined('YII_DEBUG') or define('YII_DEBUG',true);


require_once($yii);

Yii::createWebApplication($config)->run();

Ok, I changed the database in the main.php config file to the “test” database and now it works … so it seems, that somewhere it’s using the main.php config instead of the test.php … wtf…

If your main configuration is not too big, you can just copy it over to test configuration, and then skip the array merge.

Still, strange that it doesn’t override…

Hmm … well, that’s a solution, but a bit hacky :wink: … when I have to change something in the main.php … always got a second place to change that stuff as well :-(.

Is there a way to figure out, why the override doesn’t work when the database inserts come through the views?

… because - as sayed before - a call to a model function from the selenium test files works. O_o

Do you specify index-test.php in the url you ask Selenium to access?

Edit:

I missed this statement (obviously a Selenium call)

URL rules? Try to verify whether the actionCreate call uses index.php as entry script.

/Tommy

Ahh! Tommy, I think you got it ;-).

The actionCreate is called - in this case - via javascript:


<script language="javascript">

    var uri = '/startregie/statistic/create';

.......

.........

...........

$.post(uri, {

            input_number: inputNumber,

            answer: $(inputField).val()

        } );

.......

........

.........

</script>

I guess I have to make this link dynamic? … anyone an idea how I could solve this?

Obviously you use urlManager and path format.

First of all I think you should use the createUrl() method (of course from PHP-land) for generating the url, this way it will reflect the current urlManager config.

If this doesn’t help, next I would try to set showScriptName to true in the test config (should be possible to overwrite).

(I didn’t try this)

/Tommy

Thank you so much Tommy!

Finally the use of “createUrl()” didn’t solve anything, but setting showScriptName to true did the work. Maybe someone could explain to me, why this did the job? I’d like to understand, why it didn’t work in first place? :slight_smile:

… and I just can repeat myself: I f***ing LOVE Yii! Great job guys!

If the script name is hidden in the URL’s, you’ll have to change the htaccess file’s RewriteRule to use index-test.php instead of index.php.

/Tommy