How to ensure that Laravel 5.5 is running a test? - php

I have some methods in my app that I check for if (env('APP_DEBUG')) on and return true (or whatever) if we're in debug mode rather than doing a certain DB or API call.
The problem is when I run phpunit, the app is still in debug mode, so it doesn't "really" run the test against the actual code.
Is it possible to check if a test is being run, so I could do if (env('APP_DEBUG') || $testing)? Or is there a better way to handle this case?

You're looking for App::runningUnitTests().
Remember that you shouldn't use env() outside your configuration files, instead use config('app.debug'). This ensures that your code works with a cached configuration.
It's impossible to answer "is there a better way" without having more details.

Rather than update your application to check if tests are running, you could disable debug mode in your test environment by updating your phpunit.xml file:
<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="APP_DEBUG" value="false"/>
</php>
Also, you should not use the env function outside of configuration files. The env function will just return null if you are using the config cache
https://laravel.com/docs/5.5/configuration#configuration-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.
Use config('app.debug') instead of env('APP_DEBUG').

Related

Laravel parallel test cant create the database

I am trying to run laravel feature tests in parallel mode as it is in document. My phpunit.xml is configed as below :
<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="mysql"/>
</php>
and I am running the tests with this command :
php artisan test --parallel
The result is all tests fail with this error message :
PDOException: SQLSTATE[HY000] [1049] Unknown database 'mydbname_test_11'
should I create this database before starting test or laravel creates that automatically ?
Yes, the database must exist before you run your test. another thing to note is that parallel unlike PHP artisan test, will not migrate your database for you. So what I found works best is to migrate my database before running the test in parallel.
When running tests in parallel mode with Laravel, it is necessary to create a separate database for each parallel test process. Laravel will not create these databases automatically, so it is up to you to ensure that they exist before running your tests. You can either create the databases manually, or you can use a tool like PHPUnit's #database annotations to automatically create and tear down the necessary databases before and after each test run.
In your phpunit.xml file, you can specify the DB_DATABASE and DB_USERNAME environment variables to control which database Laravel should use for testing. For example:
<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="mysql"/>
<env name="DB_DATABASE" value="mydbname_test_%s"/>
<env name="DB_USERNAME" value="myusername"/>
</php>
The %s in the DB_DATABASE value will be replaced with the current test process number, so each test process will use a different database. You will need to make sure that a database with the appropriate name exists for each test process before running your tests.
You can then use the #database annotation in your test classes to control the creation and destruction of these databases.

laravel PHPUnit test configuration been overriden by .env

I'm having this weird problem that doesn't always happen and sometimes php artisan config:cache fixes it.
Sometimes when I run phpunit test, it loads the local environment configuration and messes up the database. Changing values in phpunit.xml doesn't seem to have any effect at all.
Any idea why this happening and how to fix this?
I've tried overriding the createsApplication method and manually set the environment variables, clearing cache, caching config, PHPStorm test suit with custom configuration.
<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>

Laravel Testing - migrating/refreshing wrong environment

Laravel v5.5.14
PHPUnit v6.4.1
I have a Laravel application with a number of feature tests. My base TestCase uses the RefreshDatabase trait for triggering a DB refresh before each test, and the env variables in my phpunit.xml looks like so;
<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
The intention being to leave the development mysql DB connection alone and run the tests using sqlite in memory. Despite these settings (and clearing cached config etc) the DB refresh always refreshes the mysql connection DB.
I've looked into the functionality within RefreshDatabase and debugged the refreshDatabase method, which contians;
$this->usingInMemoryDatabase()
? $this->refreshInMemoryDatabase()
: $this->refreshTestDatabase();
And usingInMemoryDatabase always returns false. Looking at the content of that method, when retrieving the DB_CONNECTION from config it always returns mysql, even though it should be being overridden by the env variable above.
What is going on here?
Run php artisan config:clear before running the tests to clear the cache to make sure the config variables are not cached from a wrong environment. If this doesn't help run PHPUnit using your IDE (e.g PHPStorm) and specifically select your project phpunit.xml

Laravel phpunit testing mail sending

Im trying to test mail sending in laravel 5.1 application.
I need run tests on prod server.
I need MAIL_DRIVER=log at app environment for running test.
And MAIL_DRIVER=smtp for production in my .env file.
I edited phpunit.xml at application root folder and added line:
<env name="MAIL_DRIVER" value="log"/>
<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="MAIL_DRIVER" value="log"/>
</php>
The problem is when I running test it still use MAIL_DRIVER=smtp
Any idea what is wrong?
Try to redefine mail transport type directly. Changing environment constants will do nothing (or share the code where MAIL_DRIVER is used).

Laravel 5 : How to set environment mode

I mm trying to set 3 mode in laravel 5 Example : mode local , staging , production
I am setting environment 3 mode in .env but I try to separate to
.local.env , .staging.env and production.env someone here have any idea to do like this ?
Now i'm try in .env -> APP_ENV to 3 mode right now :)
Thank you
Other answers/comments are wrong.
You only store one .env per environment. That is:
Your local machine will have a .env with your local config
The staging maching will have a .env with your staging config,
and
Your production maching will have a .env with your production config
So it is always one .env file per machine. Laravel will load that config from that file.
note that .env file is in .gitignore, .env.example is not
When testing on local machine using PHPUnit you can add env variables in phpunit.xml
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_DEBUG" value="true"/>
<env name="APP_KEY" value="some crazy value"/>
<env name="DB_DRIVER" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
</php>

Categories