Home > OS >  php artisan test still loads .env instead of .env.testing
php artisan test still loads .env instead of .env.testing

Time:12-18

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

CodePudding user response:

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.

CodePudding user response:

Finally, I've found a solution. It wasn't the permission or anything

It's the way that laravel expect all users to deal with testing.

Laravel thinks that all users running their tests and developing on different computers or simply they expect us to have docker containers.

For me it's a lot cost of memory usage if I have to use docker on my windows.

So I prefer to not use anything but windows and wamp.

In my case the solution is defining a new place for caching the configs for testing.

I have made a little change in phpunit.xml and define a new place for APP_CONFIG_CACHE like following.

phpunit.xml:

<!-- ... -->
<php>
    <!-- ... -->
    <server name="APP_CONFIG_CACHE" value="bootstrap/cache/config-testing.php" force="true"/>
    <!-- ... -->
</php>
<!-- ... -->

But it's not enough because laravel wont cache the configuration by itself in CreatesApplication trait, So I had to make some changes there too:

./tests/CreatesApplication.php:


<?php

namespace Tests;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Artisan;

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

        $app->make(Kernel::class)->bootstrap();
        
        // create config cache manually
         Artisan::call('config:cache');

        return $app;
    }

}

Now everything works fine.

php artisan config:cache will recreate config cache but in my case If I don't change anything in .env file, or config files, then I don't need to run php artisan optimize or php artisan config:clear and my web pages works fine in browser, also I'm able to make changes in .env.testing file without any concerns about that every time I want to switch between test mode and web mode, I have to take care of the config caches.

  • Related