M
M
matperez2015-03-16 19:19:33
Yii
matperez, 2015-03-16 19:19:33

Why do tests in Codeception crash during mass launch, but work individually?

Hello!
I write unit tests in Codeception. My app template is Yii2-basic-app. Individually, each test runs fine, however, if you run them in bulk through codecept run unit, some of them fail.
By debugging, I found out that Yii::$app disappears in these tests. Accordingly, the tests fail on any call to Yii::$app->charset or Yii::$app->timeZone.
Bootstrap for unittests is simple, it is executed once during mass launch.

// add unit testing specific bootstrap code here
$config = require(dirname(__DIR__) . '/config/unit.php');
new \yii\console\Application($config);

It is also not clear why Yii::$app reappears in the following tests. I can't find any pattern, but the same tests always fail.
Has anyone experienced this? Where to dig to find solutions?
Here, for example, is a simple test that crashes on mass launch.
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 succeeds, but the other two fail:
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

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
matperez, 2015-03-16
@matperez

That's how you always ask a question, that's how you find a solution...
Tests must be inherited from yii\codeception\TestCase or yii\codeception\DbTestCase. They have application initialization at the beginning of each test.
In the test that crashed during mass launch, \Codeception\TestCase\Test was used.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question