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

时间:2015-07-28 16:18:41

标签: php laravel phpunit laravel-5 laravel-dotenv

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.

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

10 个答案:

答案 0 :(得分:11)

将您的.env复制到.env.testing,然后修改.env.testing文件并更改APP_ENV参数,使其成为APP_ENV=testing,这样您就可以能够在这个新文件中指定你的设置

如果您不想创建新的.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>

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

对于这个例子,我指定phpunit使用名为testing的sqlite数据库。

顺便在config / database.php中添加了这个 'default' => env('DB_CONNECTION', 'mysql'),默认使用mysql,除非我指定不同的东西,如本例所示。

答案 1 :(得分:9)

您可以覆盖And Add below code on your view page: <?php $map_options = array( "id" => "map_canvas", "width" => "500px", "height" => "500px", "localize" => false, "zoom" => 10, "address" => "Manhattan, NY", "marker" => true, "infoWindow" => true ); ?> // print the default map <?= $this->GoogleMap->map($map_options); ?> // add the marker with latitude and longitude <?= $this->GoogleMap->addMarker("map_canvas", 1, array("latitude" => 40.69847, "longitude" => -73.9514)); ?> // add the marker with address <?= $this->GoogleMap->addMarker("map_canvas", 2, "Queens, NY"); ?> [1]: https://github.com/marcferna/CakePHP-GoogleMapHelper/blob/master/GoogleMapHelper.php 文件中使用的 lat = 51.513540; longitude = -0.155107; fullName = "Zara"; zoom = 21; String uri = String.format(Locale.ENGLISH, "geo:" + lat + "," + longitude + "?z="+ zoom + "&q=" + fullName ); 文件,该文件将引导框架进行测试。

更具体:

测试/ TestCase.php

.env

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

请注意,/** * 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; } 中定义的任何设置都将覆盖此配置。

更新

启动Laravel5.4,tests\TestCase中找不到TestCase功能。它已被移至tests\CreatesApplication特征。

答案 2 :(得分:3)

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

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

DB_DATABASE=local_test_db
DB_USERNAME=root

确保您的phpunit.xml文件至少有一个env var:

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

最后,您的基本测试用例(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();
}

答案 3 :(得分:2)

从此link

方法1

步骤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,
        ],
    ],
];

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

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

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

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

步骤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

步骤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

注意:如果您不想使用数据库事务,可以使用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();
    }
}

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

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

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

这样就可以了,因此PHPUnit会在加载你的app之前更改env。如果运行测试,你的env已经在测试了

答案 6 :(得分:0)

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

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

APP_ENV=testing php artisan migrate --database=sqlite_testing

答案 7 :(得分:0)

这是2019年。 在解决这个问题之前,我已经解决了很长时间。 这是我的假设: 如果您还发现很难使您的PHPUnit.xml与.env.testing文件进行对话,那么您很可能正在使用PHPStorm! 如果是这样,请继续阅读。 如果没有,不...这将无济于事。 好... 在这里,您去了:

  1. 转到PHPStorm的“设置”,或直接按Ctrl + Alt + S。
  2. 转到语言和框架>> PHP >>测试框架
  3. 在“测试运行器”选项卡下,单击“默认配置文件”,然后选择(通过单击文件夹图标)项目的PHPUnit.xml文件的路径。

这是使xml文件中的所有更改生效。 因此,继续,创建.env.testing文件,创建用于测试的首选数据库配置变量...然后尝试再次运行测试!

答案 8 :(得分:0)

过去几个月来一直为此苦苦挣扎,今天才遇到this Github issue。 从那里提出的解决方案中,您应该在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);
    }
}

如果在进行上述修改后仍遇到此问题,则可以按照以下说明重新构建整个应用程序,以进一步解决问题:

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

这对我来说很好。

答案 9 :(得分:0)

已更新

对于Laravel 5.8用户,您可以在项目的根目录中创建一个 console.log(extractedErrors["errors"].message) 文件。

使用其他数据库,例如my_app_testing。

因此,它将是.env

.env.testing

和.env.testing

DB_DATABASE=clinical_managment

然后,清除配置。

DB_DATABASE=clinical_managment_testing

重新运行测试。在我的设置中,它可以正常工作。