如何在Laravel 5中为phpunit指定不同的.env文件?

时间:2021-12-25 08:15:33

I have a .env file containing my database connection details, as is normal for Laravel 5. I want to override these for testing, which I can do in phpunit.xml. However, doing this seems to go against the philosophy of .env which is not to commit environmental configurations, particularly passwords.

我有一个包含我的数据库连接详细信息的.env文件,正如Laravel 5一样。我想覆盖这些以进行测试,我可以在phpunit.xml中进行测试。但是,这样做似乎违背了.env的理念,即不提交环境配置,特别是密码。

Is it possible to have something like .env.testing and tell phpunit.xml to read from that?

是否有可能像.env.testing这样的东西并告诉phpunit.xml从中读取?

7 个解决方案

#1


8  

Copy your .env to .env.testing, then edit the .env.testing file and change the APP_ENV parameter to make it like this APP_ENV=testing this way you will be able to specify your settings int this new file

将.env复制到.env.testing,然后编辑.env.testing文件并更改APP_ENV参数使其像这样APP_ENV =以这种方式测试你可以在这个新文件中指定你的设置

In case you don't want to create a new .env.testing file you have to specify your variables in the phpunit.xml in the php section with the values you need, something like this

如果您不想创建新的.env.testing文件,您必须在php部分的phpunit.xml中使用您需要的值指定变量,如下所示

<php>
    <env name="APP_ENV" value="testing"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value="testing"/>
</php>

Just use the key values in the name section and the value of that key in the value section.

只需使用名称部分中的键值和值部分中该键的值即可。

For this example I am specifying phpunit to use an sqlite database with the name of testing.

对于这个例子,我指定phpunit使用带有测试名称的sqlite数据库。

By the way in config/database.php I added this 'default' => env('DB_CONNECTION', 'mysql'), to use mysql by default unless I specify something diferent, as in this case.

顺便说一句,我在config / database.php中添加了这个'default'=> env('DB_CONNECTION','mysql'),默认情况下使用mysql,除非我指定不同的东西,就像在这种情况下一样。

#2


5  

You could override the .env file being used in your TestCase file, where the framework is booted for testing.

您可以覆盖TestCase文件中使用的.env文件,该文件将引导框架进行测试。

More specific:

tests/TestCase.php

/**
 * Creates the application.
 *
 * @return \Illuminate\Foundation\Application
 */
public function createApplication()
{
    /* @var \Illuminate\Foundation\Application $app */
    $app = require __DIR__ . '/../bootstrap/app.php';

    $app->loadEnvironmentFrom('.env.testing'); // specify the file to use for environment, must be run before boostrap

    $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();

    return $app;
}

All the tests extending TestCase will use this configuration file.

扩展TestCase的所有测试都将使用此配置文件。

Please note that any setting defined in phpunit.xml will override this configuration.

请注意,phpunit.xml中定义的任何设置都将覆盖此配置。

Update

Starting Laravel5.4, the createApplication function is no longer found in tests\TestCase. It has been moved to tests\CreatesApplication trait.

启动Laravel5.4,在tests \ TestCase中找不到createApplication函数。它已被移至tests \ CreatesApplication trait。

#3


2  

Create a local database on your dev machine, e.g. 'local_test_db'

在您的开发机器上创建一个本地数据库,例如'local_test_db'

Create a new .env.testing file.

创建一个新的.env.testing文件。

DB_DATABASE=local_test_db
DB_USERNAME=root

Make sure your phpunit.xml file has at least this one env var:

确保你的phpunit.xml文件至少包含以下这个env var:

<php>
    <env name="APP_ENV" value="testing"/>
</php>

Lastly your base testcase (TestCase.php) should run a migration to populate the db with tables:

最后,您的基本测试用例(TestCase.php)应该运行迁移以使用表填充数据库:

public function createApplication()
{

    $app = require __DIR__.'/../bootstrap/app.php';

    $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

    return $app;
}


public function setUp()
{
    parent::setUp();
    Artisan::call('migrate');
}

public function tearDown()
{
    Artisan::call('migrate:reset');
    parent::tearDown();
}

#4


2  

From this link

从这个链接

Method 1

Step 1: Create New Test Database Connection on Database/Config.php as below:

步骤1:在Database / Config.php上创建新的测试数据库连接,如下所示:

return [
    ... 

    'default' => env('DB_CONNECTION', 'db'),    

    'connections' => [
        'sqlite_testing_db' => [
            'driver' => 'sqlite',
            'database' => storage_path().'/testing_database.sqlite',           
            'prefix' => '',
        ],

        /**************** OR ******************/

        'testing_db' => [
            'driver' => 'mysql',
            'host' => env('TEST_DB_HOST', 'localhost'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        ],

        /** Production or database DB **/
        'db' => [
            'driver' => 'mysql',
            'host' => env('TEST_DB_HOST', 'localhost'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        ],
    ],
];

Step 2: Specify the Database Credential on .env file

步骤2:在.env文件上指定数据库凭据

TEST_DB_HOST=localhost
TEST_DB_DATABASE=laravel
TEST_DB_USERNAME=root
TEST_DB_PASSWORD=rootwdp

Step 3: Specify test db conection to be used on phpunit.xml.

步骤3:指定要在phpunit.xml上使用的测试数据库连接。

<env name="DB_CONNECTION" value="testing_db"/>
          OR Below If you prefer sqlite
<env name="DB_CONNECTION" value="sqlite_testing_db"/>                

Step 4: Migrate database to this new testing database - if you choose to use Database Transaction to Rollback insertion on the table.

步骤4:将数据库迁移到此新测试数据库 - 如果选择在表上使用Database Transaction to Rollback插入。

php artisan migrate --database=testing_db

//If using sqlite
touch storage/testing_database.sqlite
php artisan migrate --database=sqlite_testing

Step 5: Now, the Unit test with Database Transaction looks like below:

第5步:现在,使用数据库事务进行的单元测试如下所示:

<?php

use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class UserTest extends TestCase
{
    use DatabaseTransactions;

    /** @test */
    function it_test_user_can_be_saved()
    {
        factory(User::class, 2)->create();

        $users = User::all();

        $this->assertEquals(2, $users->count());
    }
}

//Run Php Unit
-> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php

Note: If you prefer not to use Database Transaction, you can use setup and teardown method on TestCase.php class to migrate and rollback the database as below:

注意:如果您不想使用数据库事务,可以使用TestCase.php类上的setup和teardown方法来迁移和回滚数据库,如下所示:

<?php

use Illuminate\Support\Facades\Artisan;

class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    ...

    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
    }

    public function tearDown()
    {
        Artisan::call('migrate:reset');
        parent::tearDown();
    }
}

#5


1  

I can't think of a way other than temporarily renaming .env.testing to .env before the unit tests start.

除了在单元测试开始之前暂时将.env.testing重命名为.env之外,我想不出办法。

You could put some logic in bootstrap/autoload.php as this is what phpunit uses as it's bootstrap file before loading the application.

您可以在bootstrap / autoload.php中添加一些逻辑,因为这是phpunit在加载应用程序之前使用的引导程序文件。

#6


1  

In your app.php change the Dotenv section

在你的app.php中更改Dotenv部分

$envFile = 'testing' === env('APP_ENV') ? '.env.testing' : null;
try {
    (new Dotenv\Dotenv(__DIR__ . '/../', $envFile))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

This will work hence PHPUnit changes the env before loading your app..so if running tests you will have the env already at testing

这将有效,因此PHPUnit会在加载您的应用程序之前更改env。如果运行测试,您将在测试时使用env

#7


0  

I did all the steps in @Sambhu Singh answer as well as followed his link. But didn't work for me in L5.5

我在@Sambhu Singh的回答中做了所有的步骤,并按照他的链接。但是在L5.5中没有为我工作

When migrating, adding/setting APP_ENV to 'testing' in front of the artisan command worked for me:

迁移时,在artisan命令前面添加/设置APP_ENV到'testing'对我有用:

APP_ENV=testing php artisan migrate --database=sqlite_testing

#1


8  

Copy your .env to .env.testing, then edit the .env.testing file and change the APP_ENV parameter to make it like this APP_ENV=testing this way you will be able to specify your settings int this new file

将.env复制到.env.testing,然后编辑.env.testing文件并更改APP_ENV参数使其像这样APP_ENV =以这种方式测试你可以在这个新文件中指定你的设置

In case you don't want to create a new .env.testing file you have to specify your variables in the phpunit.xml in the php section with the values you need, something like this

如果您不想创建新的.env.testing文件,您必须在php部分的phpunit.xml中使用您需要的值指定变量,如下所示

<php>
    <env name="APP_ENV" value="testing"/>
    <env name="CACHE_DRIVER" value="array"/>
    <env name="SESSION_DRIVER" value="array"/>
    <env name="QUEUE_DRIVER" value="sync"/>
    <env name="DB_CONNECTION" value="sqlite"/>
    <env name="DB_DATABASE" value="testing"/>
</php>

Just use the key values in the name section and the value of that key in the value section.

只需使用名称部分中的键值和值部分中该键的值即可。

For this example I am specifying phpunit to use an sqlite database with the name of testing.

对于这个例子,我指定phpunit使用带有测试名称的sqlite数据库。

By the way in config/database.php I added this 'default' => env('DB_CONNECTION', 'mysql'), to use mysql by default unless I specify something diferent, as in this case.

顺便说一句,我在config / database.php中添加了这个'default'=> env('DB_CONNECTION','mysql'),默认情况下使用mysql,除非我指定不同的东西,就像在这种情况下一样。

#2


5  

You could override the .env file being used in your TestCase file, where the framework is booted for testing.

您可以覆盖TestCase文件中使用的.env文件,该文件将引导框架进行测试。

More specific:

tests/TestCase.php

/**
 * Creates the application.
 *
 * @return \Illuminate\Foundation\Application
 */
public function createApplication()
{
    /* @var \Illuminate\Foundation\Application $app */
    $app = require __DIR__ . '/../bootstrap/app.php';

    $app->loadEnvironmentFrom('.env.testing'); // specify the file to use for environment, must be run before boostrap

    $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();

    return $app;
}

All the tests extending TestCase will use this configuration file.

扩展TestCase的所有测试都将使用此配置文件。

Please note that any setting defined in phpunit.xml will override this configuration.

请注意,phpunit.xml中定义的任何设置都将覆盖此配置。

Update

Starting Laravel5.4, the createApplication function is no longer found in tests\TestCase. It has been moved to tests\CreatesApplication trait.

启动Laravel5.4,在tests \ TestCase中找不到createApplication函数。它已被移至tests \ CreatesApplication trait。

#3


2  

Create a local database on your dev machine, e.g. 'local_test_db'

在您的开发机器上创建一个本地数据库,例如'local_test_db'

Create a new .env.testing file.

创建一个新的.env.testing文件。

DB_DATABASE=local_test_db
DB_USERNAME=root

Make sure your phpunit.xml file has at least this one env var:

确保你的phpunit.xml文件至少包含以下这个env var:

<php>
    <env name="APP_ENV" value="testing"/>
</php>

Lastly your base testcase (TestCase.php) should run a migration to populate the db with tables:

最后,您的基本测试用例(TestCase.php)应该运行迁移以使用表填充数据库:

public function createApplication()
{

    $app = require __DIR__.'/../bootstrap/app.php';

    $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

    return $app;
}


public function setUp()
{
    parent::setUp();
    Artisan::call('migrate');
}

public function tearDown()
{
    Artisan::call('migrate:reset');
    parent::tearDown();
}

#4


2  

From this link

从这个链接

Method 1

Step 1: Create New Test Database Connection on Database/Config.php as below:

步骤1:在Database / Config.php上创建新的测试数据库连接,如下所示:

return [
    ... 

    'default' => env('DB_CONNECTION', 'db'),    

    'connections' => [
        'sqlite_testing_db' => [
            'driver' => 'sqlite',
            'database' => storage_path().'/testing_database.sqlite',           
            'prefix' => '',
        ],

        /**************** OR ******************/

        'testing_db' => [
            'driver' => 'mysql',
            'host' => env('TEST_DB_HOST', 'localhost'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        ],

        /** Production or database DB **/
        'db' => [
            'driver' => 'mysql',
            'host' => env('TEST_DB_HOST', 'localhost'),
            'database' => env('TEST_DB_DATABASE', 'forge'),
            'username' => env('TEST_DB_USERNAME', 'forge'),
            'password' => env('TEST_DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => false,
        ],
    ],
];

Step 2: Specify the Database Credential on .env file

步骤2:在.env文件上指定数据库凭据

TEST_DB_HOST=localhost
TEST_DB_DATABASE=laravel
TEST_DB_USERNAME=root
TEST_DB_PASSWORD=rootwdp

Step 3: Specify test db conection to be used on phpunit.xml.

步骤3:指定要在phpunit.xml上使用的测试数据库连接。

<env name="DB_CONNECTION" value="testing_db"/>
          OR Below If you prefer sqlite
<env name="DB_CONNECTION" value="sqlite_testing_db"/>                

Step 4: Migrate database to this new testing database - if you choose to use Database Transaction to Rollback insertion on the table.

步骤4:将数据库迁移到此新测试数据库 - 如果选择在表上使用Database Transaction to Rollback插入。

php artisan migrate --database=testing_db

//If using sqlite
touch storage/testing_database.sqlite
php artisan migrate --database=sqlite_testing

Step 5: Now, the Unit test with Database Transaction looks like below:

第5步:现在,使用数据库事务进行的单元测试如下所示:

<?php

use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class UserTest extends TestCase
{
    use DatabaseTransactions;

    /** @test */
    function it_test_user_can_be_saved()
    {
        factory(User::class, 2)->create();

        $users = User::all();

        $this->assertEquals(2, $users->count());
    }
}

//Run Php Unit
-> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php

Note: If you prefer not to use Database Transaction, you can use setup and teardown method on TestCase.php class to migrate and rollback the database as below:

注意:如果您不想使用数据库事务,可以使用TestCase.php类上的setup和teardown方法来迁移和回滚数据库,如下所示:

<?php

use Illuminate\Support\Facades\Artisan;

class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    ...

    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
    }

    public function tearDown()
    {
        Artisan::call('migrate:reset');
        parent::tearDown();
    }
}

#5


1  

I can't think of a way other than temporarily renaming .env.testing to .env before the unit tests start.

除了在单元测试开始之前暂时将.env.testing重命名为.env之外,我想不出办法。

You could put some logic in bootstrap/autoload.php as this is what phpunit uses as it's bootstrap file before loading the application.

您可以在bootstrap / autoload.php中添加一些逻辑,因为这是phpunit在加载应用程序之前使用的引导程序文件。

#6


1  

In your app.php change the Dotenv section

在你的app.php中更改Dotenv部分

$envFile = 'testing' === env('APP_ENV') ? '.env.testing' : null;
try {
    (new Dotenv\Dotenv(__DIR__ . '/../', $envFile))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
    //
}

This will work hence PHPUnit changes the env before loading your app..so if running tests you will have the env already at testing

这将有效,因此PHPUnit会在加载您的应用程序之前更改env。如果运行测试,您将在测试时使用env

#7


0  

I did all the steps in @Sambhu Singh answer as well as followed his link. But didn't work for me in L5.5

我在@Sambhu Singh的回答中做了所有的步骤,并按照他的链接。但是在L5.5中没有为我工作

When migrating, adding/setting APP_ENV to 'testing' in front of the artisan command worked for me:

迁移时,在artisan命令前面添加/设置APP_ENV到'testing'对我有用:

APP_ENV=testing php artisan migrate --database=sqlite_testing