@matperez

Почему падают тесты в Codeception при массовом запуске, а по отдельности работают?

Здравствуйте!

Пишу юнит тесты в Codeception. Шаблон приложения у меня Yii2-basic-app. По отдельности каждый тест выполняется нормально, однако, если запустить их скопом через codecept run unit, некоторые из них падают.

Путем отладки выяснил, что в этих тестах пропадает Yii::$app. Соответственно, тесты падают на каком-нибудь обращении к Yii::$app->charset или Yii::$app->timeZone.

Бутстрап для юниттестов простой, выполняется он один раз при массовом запуске.
// add unit testing specific bootstrap code here
$config = require(dirname(__DIR__) . '/config/unit.php');
new \yii\console\Application($config);


Непонятно так же почему Yii::$app снова появляется в следующих тестах. Какой-то закономерности найти не могу, но падают всегда одни и те же тесты.

Кто-нибудь сталкивался с таким? Куда копать для поиска решений?

Вот, например, простой тест, который падает при массовом запуске.
class OrderFormTest extends \Codeception\TestCase\Test
{
    use Specify;

    /**
     * @var \UnitTester
     */
    protected $tester;

    // tests
    public function testCreate()
    {
        $form = new OrderForm();

        $this->specify('it should be able to instantiate', function() use ($form) {
            expect('it is instance of OrderForm model', get_class($form))->contains('OrderForm');
        });

    }

    public function testLoad()
    {
        $form = new OrderForm();

        $form->scenario = 'testing';

        $data = $this->getFormData();

        $this->specify('it should be able to load data', function() use ($form, $data) {
            expect('method returned true', $form->load($data, ''))->true();
            expect('attributes are loaded', $form->attributes)->equals($data);
        });
    }

    public function testValidate()
    {
        $form = new OrderForm();

        $form->scenario = 'testing';

        $data = $this->getFormData();

        $this->specify('it should properly validate data', function() use ($form, $data) {
            $form->validate();
            expect('it require name', $form->getErrors('name'))->notEmpty();
            expect('it require phone', $form->getErrors('phone'))->notEmpty();
            expect('it require email', $form->getErrors('email'))->notEmpty();
            expect("it require paymentType", $form->getErrors('paymentType'))->notEmpty();
            expect("it doesn't require comment", $form->getErrors('comment'))->isEmpty();
            expect("it doesn't require organization", $form->getErrors('organization'))->isEmpty();

            $form->load($data);
            $form->paymentType = Order::PAYMENT_CASHLESS;
            $form->organization = null;
            $form->validate();
            expect('it require organization when payment type is cashless', $form->getErrors('organization'))->notEmpty();
        });
    }

    /**
     * @return array
     */
    protected function getFormData()
    {
        $faker = Factory::create();

        $data = [
            'name' => $faker->name,
            'phone' => $faker->phoneNumber,
            'email' => $faker->email,
            'comment' => $faker->sentence(),
            'organization' => $faker->word,
            'paymentType' => 1,
            'verifyCode' => null,
        ];

        return $data;
    }

}


Test Create проходит успешно, а два остальных падают:

2) models\OrderFormTest::testLoad | it should be able to load data
yii\base\ErrorException: Trying to get property of non-object

#1  /home/vhosts/2/vendor/yiisoft/yii2/di/Container.php:372
#2  /home/vhosts/2/vendor/yiisoft/yii2/di/Container.php:372
#3  /home/vhosts/2/vendor/yiisoft/yii2/di/Container.php:151
#4  /home/vhosts/2/vendor/yiisoft/yii2/BaseYii.php:344
#5  /home/vhosts/2/vendor/yiisoft/yii2/validators/Validator.php:204
#6  /home/vhosts/2/vendor/yiisoft/yii2/base/Model.php:422
#7  /home/vhosts/2/vendor/yiisoft/yii2/base/Model.php:386
#8  /home/vhosts/2/vendor/yiisoft/yii2/base/Model.php:184
#9  /home/vhosts/2/vendor/yiisoft/yii2/base/Model.php:715
#10 /home/vhosts2/vendor/yiisoft/yii2/base/Model.php:659
  • Вопрос задан
  • 983 просмотра
Решения вопроса 1
@matperez Автор вопроса
Вот так всегда, как задашь вопрос, так находишь решение...

Тесты нужно обязательно наследовать от yii\codeception\TestCase или yii\codeception\DbTestCase. В них есть инициализация приложения в начале каждого теста.

В том тесте что падал при массовом запуске использовался \Codeception\TestCase\Test.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы