phplaravel

php artisan test still loads .env instead of .env.testing


These are my configs:

phpunit.xml:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true"
>
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">./app</directory>
        </include>
    </coverage>
    <php>
        <server name="APP_ENV" value="testing"/>
        <server name="BCRYPT_ROUNDS" value="4"/>
        <server name="CACHE_DRIVER" value="array"/>
        <!-- <server name="DB_CONNECTION" value="sqlite"/> -->
        <!-- <server name="DB_DATABASE" value=":memory:"/> -->
        <server name="MAIL_MAILER" value="array"/>
        <server name="QUEUE_CONNECTION" value="sync"/>
        <server name="SESSION_DRIVER" value="array"/>
        <server name="TELESCOPE_ENABLED" value="false"/>
    </php>
</phpunit>

.env.testing

APP_NAME=metrina
APP_ENV=testing
APP_KEY=base64:***************************
APP_DEBUG=true
APP_URL=http://localhost:81
# ...
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3307
DB_DATABASE=testing
DB_USERNAME=root
DB_PASSWORD=
DB_ENGINE=InnoDB
# ...

and .env:

APP_NAME=metrina
APP_ENV=local
APP_KEY=base64:***************************
APP_DEBUG=true
APP_URL=http://localhost:81

#...

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3307
DB_DATABASE=actual
DB_USERNAME=root
DB_PASSWORD=
DB_ENGINE=InnoDB

#...

And this is my feature test:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class TradeTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function test_example()
    {
        $databaseName = \DB::connection()->getDatabaseName();
        dd($databaseName);
    }
}

and result of $ php artisan test:

Testing started at 11:11 PM ...
PHPUnit 9.5.10 by Sebastian Bergmann and contributors.

"actual"
Process finished with exit code 1

The main problem is test not using my .env.testing, otherwise it must returns

"testing"

Instead of

"actual"

I've tried php artisan optimize already


Update

This will works only if I first manually remove the content of ./bootrap/cache directory and then run the test with following command

$ php artisan test --env=testing

Solution

  • Laravel does not load the .env files when you have cached your config. Laravel warns that the environment variables should only be accessed inside the config files, so once the config files are cached, there is no reason to load the .env files anymore.

    In this case, Laravel's expectation is to not cache your config in your development environment. Only cache your config in your production environment.

    From the documentation on config caching:

    If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files. Once the configuration has been cached, the .env file will not be loaded; therefore, the env function will only return external, system level environment variables.