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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31681914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:04:29  来源:igfitidea点击:

How to specify a different .env file for phpunit in Laravel 5?

phplaravellaravel-5phpunitphpdotenv

提问by Gnuffo1

I have a .envfile 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 .envwhich is not to commit environmental configurations, particularly passwords.

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

Is it possible to have something like .env.testingand tell phpunit.xmlto read from that?

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

回答by Dimitri Acosta

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

复制您的.envto .env.testing,然后编辑.env.testing文件并更改APP_ENV参数以使其像APP_ENV=testing这样您将能够在这个新文件中指定您的设置

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

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

<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 使用一个名为 testing 的 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,除非我指定了一些不同的东西,就像在这种情况下一样。

回答by Bogdan

You could override the .envfile being used in your TestCasefile, where the framework is booted for testing.

您可以覆盖.env文件中正在使用的TestCase文件,框架在其中启动以进行测试。

More specific:

更加具体:

tests/TestCase.php

测试/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 TestCasewill use this configuration file.

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

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

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

Update

更新

Starting Laravel5.4, the createApplicationfunction is no longer found in tests\TestCase. It has been moved to tests\CreatesApplicationtrait.

从 Laravel5.4 开始,createApplicationtests\TestCase. 它已移至tests\CreatesApplicationtrait。

回答by Wale

This is 2019.

这是 2019 年。

I had this issues for so long until I was able to figure it out.

我有这个问题很长时间,直到我能够弄清楚。

And here is my assumption:

这是我的假设:

If you are also finding it difficult to make your PHPUnit.xml talk with your .env.testing file, then you are likely using PHPStorm!

如果您还发现很难让您的 PHPUnit.xml 与您的 .env.testing 文件对话,那么您很可能正在使用 PHPStorm!

If this is true, continue reading.

如果这是真的,请继续阅读。

If not, nope...this won't help.

如果没有,不……这无济于事。

Ok...

好的...

Here you go:

干得好:

  1. Go to Settings of your PHPStorm or just simply press Ctrl + Alt + S.
  2. Go to Languages And Frameworks >> PHP >> Test Frameworks
  3. Under Test Runner tab, click Default configuration file and select (by clicking the folder icon) the path of your project's PHPUnit.xml file.
  1. 转到 PHPStorm 的设置或只需按 Ctrl + Alt + S。
  2. 转到语言和框架 >> PHP >> 测试框架
  3. 在 Test Runner 选项卡下,单击 Default configuration file 并选择(通过单击文件夹图标)项目的 PHPUnit.xml 文件的路径。

What this does is to make all your changes in the xml file take effect. So, go ahead, create the .env.testing file, create your preferred DB config variables for test...and try running your tests again!

这样做是为了使您在 xml 文件中的所有更改生效。所以,继续,创建 .env.testing 文件,为测试创建你喜欢的数据库配置变量......然后再次尝试运行你的测试!

回答by S..

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();
}

回答by Sambhu Singh

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 步:将数据库迁移到这个新的测试数据库 - 如果您选择使用数据库事务来回滚表上的插入。

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();
    }
}

回答by Julius Koronci

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..所以如果运行测试,您将已经在测试中

回答by Nisal Gunawardana

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

回答by fire

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 在加载应用程序之前使用的引导程序文件。

回答by Leonel Elimpe

Been struggling with this for a few months now and just came across this Github issuetoday. From the solutions proposed there, here's what you should do in your CreatesApplication.php file (to delete the cached config in order to have Laravel load the test environment):

几个月来一直在为此苦苦挣扎,今天刚刚遇到这个 Github 问题。根据那里提出的解决方案,您应该在 CreatesApplication.php 文件中执行以下操作(删除缓存的配置以使 Laravel 加载测试环境):

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

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

    $this->clearCache(); // NEW LINE -- Testing doesn't work properly with cached stuff.

    return $app;
}

/**
 * Clears Laravel Cache.
 */
protected function clearCache()
{
    $commands = ['clear-compiled', 'cache:clear', 'view:clear', 'config:clear', 'route:clear'];
    foreach ($commands as $command) {
        \Illuminate\Support\Facades\Artisan::call($command);
    }
}

If you're still experiencing this issue after the above modification, you can go further by rebuilding the entire application as follows:

如果上述修改后您仍然遇到此问题,您可以通过重新构建整个应用程序来进一步,如下所示:

public function createApplication()
{
    $createApp = function() {
        $app = require __DIR__.'/../bootstrap/app.php';
        $app->make(Kernel::class)->bootstrap();
        return $app;
    };

    $app = $createApp();
    if ($app->environment() !== 'testing') {
        $this->clearCache();
        $app = $createApp();
    }

    return $app;
}

This is working just fine for me.

这对我来说很好用。

回答by Pyae Sone

Updated

更新

For Laravel 5.8 users, you may create a .env.testingfile in the root of your project.

对于 Laravel 5.8 用户,您可以.env.testing在项目的根目录中创建一个文件。

Use a different db, like my_app_testing.

使用不同的数据库,如 my_app_testing。

So, it will be, in .env

所以,它会在 .env 中

DB_DATABASE=clinical_managment

and in .env.testing

并在 .env.testing

DB_DATABASE=clinical_managment_testing

Then, make config clear.

然后,明确配置。

php artisan config:clear

Re-run the test. In my setup, it works.

重新运行测试。在我的设置中,它有效。