don't check env(), check config(). Whatever is in config, is what's actually being used.
dump(config('app.env'));
I can't get tests to run from a testing environment, they always seem to run using the 'local' variables set in the .env file rather than the settings in phpunit.xml
I've run.
php artisan config:clear
my phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
</php>
</phpunit>
But if I echo out the APP_ENV variable in testing
dump(env('APP_ENV'));
I still get it showing "local"
Anyone run into this problem before?
don't check env(), check config(). Whatever is in config, is what's actually being used.
dump(config('app.env'));
Thanks for that.
Tried
dump(config('app.env'));
But got the same result: "local"
How do you run your phpunit tests? Do you run them from your command line or with some IDE?
If you run from the command line try adding --configuration /path/to/file.xml to it see the docs: https://phpunit.de/manual/6.5/en/textui.html
I always run them from within PHPStorm. And there is an option to define the phpunit.xml path. Preferences > Languages & Frameworks > PHP > Test Frameworks and there is an option to define the default configuration path.
Usually from the command line. With and without the config flag using absolute path.
Most frustrating. Can't run tests because they nuke my live dev database.
Mmm, can you figure out if it is now using your phpunit.xml file at all or only the environment settings?
Can you for example a different bootstrap file? And see if it passes that file
bootstrap="vendor/autoload.php"
Hmm.
Right made alternative bootloader file testautoload.php
Same content but with an additional global variable to test.
$GLOBALS['bootload'] = "Testing New Loader";
And in the test file:
dump($GLOBALS['bootload']);
Running phpunit prints: "Testing New Loader", so at least I now know that the phpunit.xml is being read.
But it would appear system variables are somehow still being set and overriding the ones specified in the phpunit.xml file.
Anyone else got some suggestions, I just can't figure this one out.
Could always go the ol' reliable clean slate rebuild on the OS.
I don't have a solution. But are all of the ENV variables in your phpunit.xml ignored? Or only the config('app.env') ? What Laravel version are you using? And how does your test look like? Do you have a default Laravel test or do you have your own setUp methods maybe?
For some reason it was persisting the environment variables to the system, and they were taking precedence.
I couldn't figure out why, or how to stop it. So I nuked the HDD.
Got a fresh OS, and the problem has magically vanished. I guess the cause will remain a mystery.
But for historical records:
Laravel: 5.6* Tests were stock, with one simple create user, update user, verify name on page. No custom setUp or teardowns.
Solved the issue.
It turned out to be my shell. ZSH in this case. No idea what or why.
@SHANETURNER - I'm running into this exact issue with a fresh install of Laravel 5.8 :( trying to figure out why this is happening. Even starting up bash and running phpunit triggers the issue.
Did you by any chance run php artisan config:cache? If so - try to clear it php artisan config:clear and then run your tests again.
Came here to confirm that this was in fact the solution.
Tried removing Oh My Zsh shell as well but that didn't do anything. artisan config:clear did the trick!
That was the solution. Thanks, i don't know when I ran config:cache, but that was the problem.
Awesome! Worked for me. Thank you :)
I am having the exact same problem @shaneturner. No idea why! Anyone got a solution for this problem or it remains a mystery?
I even tried to add force="true" to APP_ENV on phpunit.xml, but had no success...
For me, removing and reinstalling ZSH fixed the issue.
Must have been system variables conflicting with local project ones. Almost a year ago now, so I don't remember the details.
Thanks a lot for the answer. Got it here! :)
This absolutely has to do with your system environment variables. First always check your shell echo $APP_ENV or the specific environment variable that is not being changed the way you'd wish. If the shell has the variable set, it will ALWAYS take precident no matter what you do with your .env or phpunit.xml files.
To expand very slightly on @daveawb 's excellent point, you can use unset APP_ENV to clear the offending environment variable from your shell. Thereafter the tests will use the one set in phpunit.xml (or at least, they did for me).
You are a genius man, thank you
I am trying to ** read ** values from my .env file and access them in phpunit.xml Is there a way to do this? I do not want to define a new .env.testing file and have to maintain it separately, I just want to override 2 variables in my .env file.
I have tried:
<server name="DB_CONNECTION" value="config('DB_CONNECTION_PHPUNIT')"/>
<server name="DB_CONNECTION" value="env('DB_CONNECTION_PHPUNIT')"/>
phpunit errors out with:
4) Tests\Feature\Api\PostsApiTest::non_authenticated_users_cannot_access_the_following_endpoints_for_the_posts_api
InvalidArgumentException: Database connection [env('DB_CONNECTION_PHPUNIT')] not configured.
Any way to do this?
php artisan config:clear worked for me. Had already tried config:cache and cache:clear but seems they weren't enough!
Had the same problem after upgrading to Laravel 8, phpunit 9,5. Checked the usualy suspects: phpunit.xml was being read, each env setting had the force="true"attribute, config was not being cached, however, the environment variables were set pointing to the MySQL database (that I did NOT want destroyed by the tests).
Then I found this report: https://www.gitmemory.com/issue/sebastianbergmann/phpunit/4540/745359854
I am running the tests in a comtainer, as will a growing number of people. In summary:
I'll post a fix for my situation, as soon as I find one. It may be simply that local environment variables must be reset, which does not feel safe.
This rough-and-ready check in trait CreateApplication will hopefully help protect against this, at least while using sqlite for feature tests.
public function createApplication()
{
...
$app->make(Kernel::class)->bootstrap();
if (config('database.default') === 'mysql') {
throw new RuntimeException('Attempting to run tests against the mysql database; aborting');
}
...
}
I haven't got to the bottom of why Docker is important in this.
Some further research:
In a test, getenv('DB_CONNECTION') returns the environment value set in phpunit.xml, "sqlite". The getenv() function is a part of PHP, and that looks like phpunit is correctly overriding the env var. I believe phpunit does this by setting the appropriate superglobals.
However, env('DB_CONNECTION') ignores what phpunit has set, and goes back to the shell environment value, "mysql". The env() function is provided by Laravel. This behaviour changed for me between Laravel 7 and 8. I'm guessing Laravel is going somewhere other than the superglobals to get those values, or maybe the order of initialisation of Laravel and phpunit has changed?
I think this is a Laravel bug. It has been reported by a number of people, but summarily dismissed without referencing the details of the underlying issue. For example https://github.com/sebastianbergmann/phpunit/issues/4540 People are working around it by making sure environment variables are not set when testing. However, the behaviour in Laravel has changed, and that behaviour is losing people tine and databases.
Solution:
Switching from env to server swapped the two values around:
<env name="DB_CONNECTION" value="sqlite" force="true"/>
to
<server name="DB_CONNECTION" value="sqlite" force="true"/>
So in Laravel 8+ the Laravel config env() will look in the $_SERVER superglobal to get its environment variable values.
In Laravel to to 7, the Laravel config env() will look in the $_ENV supertglobal to get its environment variable values.
If you are not yet on Laravel 8, my recommendation for phpunit.xml, is to set both now, ready for a future upgrade. Both of these (and teh same for all other values):
<env name="DB_CONNECTION" value="sqlite" force="true"/>
<server name="DB_CONNECTION" value="sqlite" force="true"/>
You should not be using getenv() within your app, but using env() within teh config files instead. However, this change will help protect you from any getenv() values that have krept in.
I've just been investigating this issue after inheriting a Laravel project with an odd service provider that was throwing errors when running php artisan test.
After a bit of time I determined that phpunit.xml is used when the tests are being run but .env is used once at the beginning. And further if .env doesn't exist then the app environment (APP_ENV) defaults to "production".
So the logging of my tests shows one instance of the app being initialised in "production" and then lots of "testing".
My workaround for this issue is to run phpunit directly rather than through artisan. In my case it's for CI integration so I don't need the pretty CLI user interface. Or I'll set the environment variables on my CI server if I have to.
check if your docker-compose.yml has env_file: .env declaration. It makes your container share .env application variables with container environment. So you need to remove this and maybe create another specific file to create environment variables into container. It was my case.
Thanks everyone who answered here. It lead me to properly debug which resulted to more relevant error message that also lead to more searching and finally finding the answer.
I cloned our laravel 10 project and among the team members I was the only having this issue. I'm using Laragon in my local machine. At first I was able to deduce that phpunit.xml wasn't being read. So thanks to @consil , when I changed to and did a dd('APP_ENV') it finally used the phpunit.xml variables. I also added force="true" there and got a different error. The error said sqlite driver was missing. Turned out my sqlite extension in php.ini was not enabled.
Please or to participate in this conversation.