45

How does one change database for development and testing on local system without editing the .env file each time?

I have found it quite inconvenient to practice TDD because of this.

Is it possible for a Laravel application to differentiate between normal development and testing so that it can choose the appropriate database?

gnerkus
  • 11,357
  • 6
  • 47
  • 71
George
  • 3,757
  • 9
  • 51
  • 86
  • 2
    That's exactly what the .env files are for. All you do is just keep several files, put one on the live server and then for development choose the env file you need. – Styphon Feb 05 '16 at 15:05

6 Answers6

75

Create a testing database configuration in Laravel

Edit the config\database.php file and add a testing - array into the connections array:

'connections' => [
    'testing' => [
        'driver' => env('DB_TEST_DRIVER'),
        // more details on your testing database
    ]
]

Then add the necessary variables to your .env-file.

Edit PHPUnit configuration

Open your phpunit.xml-file and add the following within your <php>-tag:

<env name="DB_CONNECTION" value="testing"/>

Now PHPUnit will run with the tests on the database you defined in the testing - array.

112Legion
  • 1,129
  • 12
  • 25
Tijmen
  • 836
  • 7
  • 9
  • 1
    Thanks, I really appreciate, I did not have to edit `config\database.php`. All I had to do was set the `DB_CONNECTION` env variable from `phpunit.xml`, which is the later part of your solution. So what I have now is `` in my phpunit.xml – George Feb 06 '16 at 10:29
  • Couldn't you add... DB_CONNECTION=testing DB_HOST=127.0.0.1 DB_PORT=test DB port DB_DATABASE=test DB name DB_USERNAME=Test DB user DB_PASSWORD=Test DB password ... to the .env file and run php artisan config:cache – Jed Lynch Nov 03 '17 at 18:09
49

For Laravel 5.5, the proper way to do this is create a testing environment file called .env.testing. Here, you can define your testing environment, including the database you want to use for testing...

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test DB
DB_USERNAME=test DB user
DB_PASSWORD=test DB password

Then run this command...

php artisan config:cache --env=testing

This will configure the cache to the .env.testing file parameters.

Here is a link to the documentation.

Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
Jed Lynch
  • 1,998
  • 18
  • 14
  • 3
    Didn't work till I ran ... php artisan config:cache --env=testing – Haris ur Rehman Jun 30 '18 at 21:39
  • You have create a .env.testing file before running the command. I would recommend the winning answer. This method should really be used to switch between dev and production. In the .env files you can define your testing server credentials, which I personally think is a better way to do it. – Jed Lynch Jul 02 '18 at 14:04
  • how to switch back to default environment? – titan Jul 17 '18 at 16:15
  • To switch back to the .env parameters run php artisan config:cache without the '--env=' part. – Jed Lynch Jul 17 '18 at 17:26
  • 1
    I did a bash script that enters to testing environment, runs the tests and then enters to normal environment again, that way I found it easier. Ty – Gjaa Mar 06 '19 at 19:45
14

If your testing database uses the same configuration but only its name is different, it would be enough to only change the selected database name by adding

<env name="DB_DATABASE" value="testing_db_name"/>

to the file phpunit.xml in the <php> node

vivanov
  • 1,422
  • 3
  • 21
  • 29
5

For those, who want to use sqlite for testing

Create a test environment file and test.sqlite file

> cp .env .env.testing
> touch test.sqlite

In .env.testing file

DB_CONNECTION=sqlite
DB_DATABASE=./test.sqlite

Followed by

php artisan config:cache --env=testing

Now again migrate your databases

php artisan migrate

if you need then seed it

php artisan db:seed

And whenever you want to use local env, run

php artisan config:cache --env=local

Please note, env name can be found in .env file as APP_ENV=local

Invincible
  • 1,418
  • 18
  • 23
0

if you need a specific database for one of your unit tests, add this code at the start of your unit test

    $connections                                    = config('database.connections');
    $connections['single_test_database_connection'] = [
        'driver'      => 'mysql',
        'host'        => env('DB_HOST', '127.0.0.1'),
        'port'        => env('DB_PORT', '3306'),
        'database'    => 'single_test_database',
        'username'    => env('DB_USERNAME', 'forge'),
        'password'    => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset'     => 'utf8mb4',
        'collation'   => 'utf8mb4_unicode_ci',
        'prefix'      => '',
        'strict'      => true,
        'engine'      => null,
    ];
    config()->set('database.connections', $connections);
    config()->set('database.default', 'single_test_database_connection');
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
-2

You can use a different .env file for each type of test. You can modify your tests/functional.suite.yml and tests/unit.suite.yml something like this:

class_name: FunctionalTester
modules:
    enabled: [Laravel5, FunctionalHelper, Asserts]
    config:
        Laravel5:
            environment_file: .env.testing

And this:

class_name: UnitTester
modules:
    enabled: [Asserts, UnitHelper, Laravel5]
    config:
        Laravel5:
            environment_file: .env.unittesting

Or you can simply modify your phpunit.xml and add environment vars like @Tijmen did above.

Pitchinnate
  • 7,517
  • 1
  • 20
  • 37