yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

Error on database configuration in second test running in codeception unit test #16878

Closed aminkt closed 6 years ago

aminkt commented 6 years ago

What steps will reproduce the problem?

I created a test class like below:

<?php

namespace common\tests\unit\models;

use common\models\Developer;
use common\tests\fixtures\DeveloperFixture;
use Faker\Factory;

class DeveloperTest extends \Codeception\Test\Unit
{
    /**
     * @var \common\tests\UnitTester
     */
    protected $tester;

    /**
     * @return array
     */
    public function _fixtures()
    {
        return [
            'developer' => [
                'class' => DeveloperFixture::class,
                'dataFile' => codecept_data_dir() . 'developer.php'
            ]
        ];
    }

    /**
     * Test validation rules of developer model.
     * This method use validationRuleDataProvider() to create some test cases.
     *
     * @see DeveloperTest::validationRuleDataProvider() Related test cases.
     */
    public function testValidationRules()
    {
        $output = new \Codeception\Lib\Console\Output([]);

        foreach ($this->validationRuleDataProvider() as $key => $example) {
            list($attribute, $value, $expect) = $example;
            $output->writeln("\n\n_____________ RUN testValidationRules case 0} __________");
            $output->writeln("Test attribute is: {$attribute}");
            $output->writeln("Test value is: {$value}");
            $output->writeln("Expected value is: {$expect}");

            $developer = new Developer();

            $developer->$attribute = $value;

            $validateValue = $developer->validate([$attribute]);

            if (!$validateValue) {
                $output->write("Validation error for {$attribute} is :\n\t");
                $output->writeln($developer->getErrors($attribute));
                $output->write("\n\n");
            }

            if ($expect) {
                $this->assertTrue($validateValue, 'Validation rule accepted.');
            } else {
                $this->assertFalse($validateValue, 'Validation rule rejected.');
            }
        }
    }

    /**
     * Data provider for testValidationRules.
     *
     * @see DeveloperTest::testValidationRules()    Test that use this provider.
     *
     * @return array
     */
    protected function validationRuleDataProvider()
    {
        $faker_fa = Factory::create('fa_IR');
        $faker_en = Factory::create();
        return [
            ['name', $faker_fa->realText(100), 1],
            ['description', $faker_fa->realText(200), 1],
            ['name', $faker_fa->numberBetween(100), 0],
            ['description', $faker_fa->numberBetween(20000000), 0],
            ['name', $faker_en->realText(100), 1],
            ['description', $faker_en->realText(200), 1],
            ['name', $faker_en->numberBetween(2000000), 0],
            ['description', $faker_en->numberBetween(20000), 0],
            ['name', $faker_fa->realText(200), 1],
            ['description', $faker_fa->realText(2000), 1],
            ['name', $faker_fa->boolean, 0],
            ['description', $faker_en->boolean, 0],
            ['name', $faker_en->realText(200), 1],
            ['description', $faker_en->realText(2000), 1],
            ['name', $faker_en->unixTime, 0],
            ['description', $faker_en->numberBetween(2147000000), 0],
        ];
    }

    /**
     * Test to saving user in database.
     * We are using Factory object to create dynamic test cases.
     */
    public function testSaving()
    {
        // use the factory to create a Faker\Generator instance
        $faker_fa = Factory::create('fa_IR');
        $faker_en = Factory::create();

        $developer = new Developer([
            'name' => $faker_en->company,
            'description' => $faker_fa->realText()
        ]);

        $saveStatus = $developer->save();

        $this->assertTrue($saveStatus, 'Developer object saved into database.');
    }

    /**
     * Test update action of Developer model.
     * We are using Factory object to create dynamic test cases.
     */
    protected function testUpdate()
    {
        $index = rand(0, 9);

        /** @var Developer $developer */
        $sample = $this->tester->grabFixture('developer')->data['developer' . $index];

        $developer = Developer::findOne(['name' => $sample['name']]);

        $this->assertNotNull($developer, "No developer object found.");

        // use the factory to create a Faker\Generator instance
        $faker_fa = Factory::create('fa_IR');
        $faker_en = Factory::create();

        $developer->name = $faker_en->company;
        $developer->description = $faker_fa->realText();

        $this->assertTrue($developer->save(), "Developer object updated.");
    }

    public function _before(){

    }

    public function _after(){

    }
}

My codeception configuration file is like below:

namespace: common\tests
actor_suffix: Tester
paths:
    tests: tests
    output: tests/_output
    data: tests/_data
    support: tests/_support
settings:
    bootstrap: _bootstrap.php
    colors: true
    memory_limit: 1024M
modules:
    config:
        Yii2:
            configFile: 'config/test-local.php'

And my unit suit configuration file is like this:

suite_namespace: common\tests\unit
actor: UnitTester
bootstrap: false
modules:
    enabled:
        - Yii2:
            part: fixtures

What is the expected result?

When i run command like codecept -c common run unit models/DeveloperTest --steps --debug -vvv all tests should be run and pass.

What do you get instead?

I got below errors that say mongodb and i18n component not configured. This problem happen in second test function running like testSave and testUpdate in DeveloperTest class.

First method run correctly.


✔ DeveloperTest: Validation rules (0.44s)
  [TransactionForcer] no longer watching new connections
  [yii\db\Connection::open] 'Opening DB connection: mysql:host=mysql;dbname=gamestore_test'
  [ConnectionWatcher] Connection opened!
  Destroying application
  [ConnectionWatcher] no longer watching new connections
  [ConnectionWatcher] closing all (2) connections
- DeveloperTest: Saving  Destroying application
  Starting application
E DeveloperTest: Saving 
E DeveloperTest: Saving (0.05s)
  Destroying application
  Suite done, restoring $_SERVER to original
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Time: 1.68 seconds, Memory: 30.00MB

There were 2 errors:

---------
1) DeveloperTest: Saving
 Test  tests/unit/models/DeveloperTest.php:testSaving

  [yii\base\InvalidConfigException] Unexpected configuration type for the "mongodb" component: boolean  

#1  /app/vendor/yiisoft/yii2/di/ServiceLocator.php:208
#2  /app/vendor/yiisoft/yii2/di/ServiceLocator.php:261
#3  /app/vendor/yiisoft/yii2/base/Component.php:180
#4  /app/vendor/yiisoft/yii2/BaseYii.php:546
#5  /app/vendor/yiisoft/yii2/base/BaseObject.php:107
#6  /app/vendor/yiisoft/yii2/base/Application.php:206
#7  yii\base\Application->__construct
#8  /app/vendor/yiisoft/yii2/di/Container.php:383
#9  /app/vendor/yiisoft/yii2/di/Container.php:156
#10 /app/vendor/yiisoft/yii2/BaseYii.php:349

---------
2) DeveloperTest: Saving
 Test  tests/unit/models/DeveloperTest.php:testSaving

  [yii\base\InvalidConfigException] Unknown component ID: i18n  

#1  /app/vendor/yiisoft/yii2/di/ServiceLocator.php:139
#2  /app/vendor/yiisoft/yii2/base/Module.php:742
#3  /app/vendor/yiisoft/yii2/base/Application.php:580
#4  /app/vendor/yiisoft/yii2/BaseYii.php:526
#5  /app/vendor/yiisoft/yii2/validators/RequiredValidator.php:60
#6  /app/vendor/yiisoft/yii2/base/BaseObject.php:109
#7  yii\base\BaseObject->__construct
#8  /app/vendor/yiisoft/yii2/di/Container.php:383
#9  /app/vendor/yiisoft/yii2/di/Container.php:156
#10 /app/vendor/yiisoft/yii2/BaseYii.php:349

ERRORS!
Tests: 2, Assertions: 16, Errors: 2.

Additional info

Q A
Yii version 2.0.15.1
PHP version 7.2.7
Operating system Linux alpine
aminkt commented 6 years ago

Is there any suggestions?

samdark commented 6 years ago

No. @SamMousa would you please take a look?

SamMousa commented 6 years ago

No idea..

aminkt commented 6 years ago

@SamMousa @samdark

I reinstalled app and when configured tests by https://github.com/yiisoft/yii2-app-advanced/blob/2.0.14/docs/guide/start-testing.md.

Then when i run vendor/bin/codecept run.

This time i don't use mongo db.

Codeception PHP Testing Framework v2.4.5
Powered by PHPUnit 7.2.7 by Sebastian Bergmann and contributors.

[common\tests]: tests from /var/www/core/common

Common\tests.unit Tests (3) --------------------------------------------------------------------------------------------------------------------------------------------------
✔ LoginFormTest: Login no user (0.28s)
E LoginFormTest: Login wrong password 
E LoginFormTest: Login wrong password (0.03s)

In Yii2.php line 346:

  Undefined property: Codeception\Module\Yii2::$connectionWatcher  

run [-o|--override OVERRIDE] [-e|--ext EXT] [--report] [--html [HTML]] [--xml [XML]] [--tap [TAP]] [--json [JSON]] [--colors] [--no-colors] [--silent] [--steps] [-d|--debug] [--coverage [COVERAGE]] [--coverage-html [COVERAGE-HTML]] [--coverage-xml [COVERAGE-XML]] [--coverage-text [COVERAGE-TEXT]] [--coverage-crap4j [COVERAGE-CRAP4J]] [--coverage-phpunit [COVERAGE-PHPUNIT]] [--no-exit] [-g|--group GROUP] [-s|--skip SKIP] [-x|--skip-group SKIP-GROUP] [--env ENV] [-f|--fail-fast] [--no-rebuild] [--] [<suite> [<test>]]

PHP Fatal error:  Uncaught RuntimeException: Command Did Not Finish Properly in /var/www/vendor/codeception/base/src/Codeception/Subscriber/ErrorHandler.php:101
Stack trace:
#0 [internal function]: Codeception\Subscriber\ErrorHandler->shutdownHandler()
#1 {main}
  thrown in /var/www/vendor/codeception/base/src/Codeception/Subscriber/ErrorHandler.php on line 101

I using one of forks of advanced-template : http://github.com/aminkt/yii2-app-api

I think problem come from this:

Undefined property: Codeception\Module\Yii2::$connectionWatcher  
SamMousa commented 6 years ago

Codeception PHP Testing Framework v2.4.5

Install the latest version of Codeception.

aminkt commented 6 years ago

I update codeception to v2.4.5 and the same thing happend.

root@709f36529dd8:/var/www/core# ../vendor/bin/codecept run -c common unit
Codeception PHP Testing Framework v2.5.1
Powered by PHPUnit 7.3.5 by Sebastian Bergmann and contributors.
Running with seed: 

Common\tests.unit Tests (3) --------------------------------------------------------------------------------------------------------------------------------------------------
✔ LoginFormTest: Login no user (0.21s)
E LoginFormTest: Login wrong password 
E LoginFormTest: Login wrong password (0.01s)
E LoginFormTest: Login correct 
E LoginFormTest: Login correct (0.00s)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Time: 1.89 seconds, Memory: 6.00MB

There were 4 errors:

---------
1) LoginFormTest: Login wrong password
 Test  tests/unit/models/LoginFormTest.php:testLoginWrongPassword

  [yii\base\InvalidConfigException] The configuration for the "db" component must contain a "class" element.  

#1  /var/www/vendor/yiisoft/yii2/di/ServiceLocator.php:205
#2  /var/www/vendor/yiisoft/yii2/di/ServiceLocator.php:261
#3  /var/www/vendor/yiisoft/yii2/base/Component.php:180
#4  /var/www/vendor/yiisoft/yii2/BaseYii.php:546
#5  /var/www/vendor/yiisoft/yii2/base/BaseObject.php:107
#6  /var/www/vendor/yiisoft/yii2/base/Application.php:206
#7  yii\base\Application->__construct
#8  /var/www/vendor/yiisoft/yii2/di/Container.php:383
#9  /var/www/vendor/yiisoft/yii2/di/Container.php:156
#10 /var/www/vendor/yiisoft/yii2/BaseYii.php:349

---------
2) LoginFormTest: Login wrong password
 Test  tests/unit/models/LoginFormTest.php:testLoginWrongPassword

  [yii\base\InvalidConfigException] Unknown component ID: i18n  

#1  /var/www/vendor/yiisoft/yii2/di/ServiceLocator.php:139
#2  /var/www/vendor/yiisoft/yii2/base/Module.php:742
#3  /var/www/vendor/yiisoft/yii2/base/Application.php:580
#4  /var/www/vendor/yiisoft/yii2/BaseYii.php:526
#5  /var/www/vendor/yiisoft/yii2/validators/RequiredValidator.php:60
#6  /var/www/vendor/yiisoft/yii2/base/BaseObject.php:109
#7  yii\base\BaseObject->__construct
#8  /var/www/vendor/yiisoft/yii2/di/Container.php:383
#9  /var/www/vendor/yiisoft/yii2/di/Container.php:156
#10 /var/www/vendor/yiisoft/yii2/BaseYii.php:349

---------
3) LoginFormTest: Login correct
 Test  tests/unit/models/LoginFormTest.php:testLoginCorrect

  [yii\base\InvalidConfigException] The configuration for the "db" component must contain a "class" element.  

#1  /var/www/vendor/yiisoft/yii2/di/ServiceLocator.php:205
#2  /var/www/vendor/yiisoft/yii2/di/ServiceLocator.php:261
#3  /var/www/vendor/yiisoft/yii2/base/Component.php:180
#4  /var/www/vendor/yiisoft/yii2/BaseYii.php:546
#5  /var/www/vendor/yiisoft/yii2/base/BaseObject.php:107
#6  /var/www/vendor/yiisoft/yii2/base/Application.php:206
#7  yii\base\Application->__construct
#8  /var/www/vendor/yiisoft/yii2/di/Container.php:383
#9  /var/www/vendor/yiisoft/yii2/di/Container.php:156
#10 /var/www/vendor/yiisoft/yii2/BaseYii.php:349

---------
4) LoginFormTest: Login correct
 Test  tests/unit/models/LoginFormTest.php:testLoginCorrect

  [yii\base\InvalidConfigException] Unknown component ID: i18n  

#1  /var/www/vendor/yiisoft/yii2/di/ServiceLocator.php:139
#2  /var/www/vendor/yiisoft/yii2/base/Module.php:742
#3  /var/www/vendor/yiisoft/yii2/base/Application.php:580
#4  /var/www/vendor/yiisoft/yii2/BaseYii.php:526
#5  /var/www/vendor/yiisoft/yii2/validators/RequiredValidator.php:60
#6  /var/www/vendor/yiisoft/yii2/base/BaseObject.php:109
#7  yii\base\BaseObject->__construct
#8  /var/www/vendor/yiisoft/yii2/di/Container.php:383
#9  /var/www/vendor/yiisoft/yii2/di/Container.php:156
#10 /var/www/vendor/yiisoft/yii2/BaseYii.php:349

ERRORS!
Tests: 3, Assertions: 2, Errors: 4.
root@709f36529dd8:/var/www/core# 
SamMousa commented 6 years ago

@aminkt, have you read the error message?

[yii\base\InvalidConfigException] The configuration for the "db" component must contain a "class" element.  

Does your database configuration have a class key?

aminkt commented 6 years ago

For mongo db i did but in new app not. let me check

aminkt commented 6 years ago

@SamMousa New error message is:

  Output path is not defined by key "paths: output"  
SamMousa commented 6 years ago

Sorry, I'm have run out of patience and will no longer be spending time on this issue. Please stop tagging people with @. I will unsubscribe from this issue; good luck with figuring out a solution!

aminkt commented 6 years ago

Problem solved. ‌I used required_onc to include my db conf and for second running test cause problem.

Sorry for wasting your time.

githubjeka commented 2 years ago

On old project to fix run tests

Output path is not defined by key "paths: output" 

need fix and update version in composer.json from * to "codeception/module-yii2": "1.0.1",