yiisoft / yii2-app-advanced

Yii 2.0 Advanced Application Template
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
1.66k stars 1.28k forks source link

Codeception tests & \Yii::$container problem #15

Closed jarekkozak closed 9 years ago

jarekkozak commented 9 years ago

Hi, I found strange behavior during tests execution. I defined class implementation using \Yii::$container like this:

\Yii::$container->set('\common\src\dict\ICarOwnerDictionary','\common\src\dict\CarOwnerDictionary');

in

 common/config/bootstrap.php

everything works ok until i try to run backend/functional tests. It is simple Cept test where I try to display page which gets dictionary implementation from \Yii::$container and display entries.

And there is the problem:

  1. If I run backend application works perfect (in browser).
  2. If I execute only functional test for backend - works fine
  3. If I execute the whole tests - does not work. There is empty \Yii:$container (debugged).

I found workaround, simply move 'common' test execution at the end - in tests/codeception.yml like this

include:
  - codeception/backend
  - codeception/frontend
  - codeception/console
  - codeception/common

paths:
  log: codeception/_output

settings:
  colors: true

After this change works perfect. It looks like only general _bootstrap file is executed once at the beginning and testing 'common' destroys \Yii:$container.

I spent a while (long while) and I only found above workaround, maybe I did something wrong? Any idea? Regards, Jarek

samdark commented 9 years ago

App instance is reset each run to achieve test isolation so you have to set your container each time.

jarekkozak commented 9 years ago

Absolutely, I undestand why it happens but my question is why _bootstrap.php is not executed at the entry to each suite?

samdark commented 9 years ago

That's how Codeception works.

jarekkozak commented 9 years ago

Hi again, I'm sorry for bothering you, I'm sure you are busy but this problem is really bothering me. According to the documentation configuration including dependecies should be be prepared in bootstrapping code. I assumed that

common/config/bootstrap.php
backend/config/bootstrap.php 

are the best place to do this. Am I right?

During test execution '*/_bootstrap.php' in tests directories fulfills entry scripts role and they are reposponsible for bootstrapping test env.

And there I found the problem described in my previous comments. Aftre further investigation I found that code in application bootstraps is executed once at the beginning of the tests and when \Yii::$container is destroyed it is not rebuild again before another tests.

I also found that changing code require_one to require solve the problem and bootstraping code is executed each time when bootstraps are called in tests e.g.

<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');

defined('YII_APP_BASE_PATH') or define('YII_APP_BASE_PATH', dirname(dirname(dirname(__DIR__))));

require_once(YII_APP_BASE_PATH . '/vendor/autoload.php');
require_once(YII_APP_BASE_PATH . '/vendor/yiisoft/yii2/Yii.php');

// Changed***********************************************************
require(YII_APP_BASE_PATH . '/common/config/bootstrap.php');
require(YII_APP_BASE_PATH . '/console/config/bootstrap.php');
//*******************************************************************
// set correct script paths
$_SERVER['SERVER_NAME'] = 'localhost';
$_SERVER['SERVER_PORT'] = '80';

Yii::setAlias('@tests', dirname(dirname(__DIR__)));

If it is not against any rules maybe it worth to change in the app-advanced test configuration code.

Best regards, Jarek

githubjeka commented 9 years ago

In bootstrap.php may redefined classes. And require likely to lead to Fatal: Cannot redeclare class, it seems to me.