Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mkudenko's avatar

How to specify a testing database in Laravel 5?

I'm trying to write unit tests for my models and controllers. I know that Laravel sets the environment to "testing" by default, but I can't figure out where to specify the test database name so it's not version controlled.

I can change the database name in phpunit.xml, but that file is commited:

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

Ideally, I'd like it to work like the .env file. .env.test maybe, that is used for unit testing?

Any help and advice are appreciated.

0 likes
7 replies
bobbybouwmann's avatar

So I'm using codeception with php unit. Mine is pretty easy setup like this:

// .env
APP_ENV=local
APP_DEBUG=true
APP_KEY=some_random_key

DB_HOST=localhost
DB_DATABASE=laravel
DB_USERNAME=homestead
DB_PASSWORD=secret
// .env.testomg
APP_ENV=testing
APP_DEBUG=true
APP_KEY=some_random_key

// Notice the extra variable
// Notice as well that I use sqlite for testing, because it's faster and easier with that ;)
DB_DEFAULT=sqlite_testing 

In my config/database file I have this

return [

    // Other stuff

    'default' => env('DB_DEFAULT', 'mysql'),

    'connections' => [

        'sqlite_testing' => [
            'driver'        => 'sqlite',
            'database'  => storage_path() . '/testing.sqlite',
            'prefix'        => '',
        ],

        'mysql' => [
            'driver'    => 'mysql',
            'host'      => env('DB_HOST', 'localhost'),
            'database'  => env('DB_DATABASE', 'forge'),
            'username'  => env('DB_USERNAME', 'forge'),
            'password'  => env('DB_PASSWORD', ''),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],  

        // Other connections

    ];

    // Other stuff
];

Note: It's important that you create the testing.sqlite file in the storage folder!

If you use Codeception like I do you only have to specify the environment file in the suite.yml file like this:

// functional.suite.yml

class_name: FunctionalTester
modules:
    enabled: [Filesystem, FunctionalHelper, Laravel5]
    config:
        Laravel5:
            environment_file: .env.testing
3 likes
mkudenko's avatar
mkudenko
OP
Best Answer
Level 3

Thank you @blackbird and @JoeDawson. I've switched from default PHPUnit to Codeception. Using Laravel5 module for specifying a testing .env file works perfectly.

Here's what I ended up using for my unit tests. Well, technically some of them are integration tests, since the database is used, but anyway.

Here's a snippet of my config/database.php file:

<?php

return [

    // other stuff

    'default' => env('DB_DEFAULT', 'mysql'),

    'connections' => [

        'sqlite_testing' => [
            'driver'   => 'sqlite',
            'database' => ':memory:',
            'prefix'   => '',
        ],

        'mysql' => [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST', 'localhost'),
        'database'  => env('DB_DATABASE', 'forge'),
        'username'  => env('DB_USERNAME', 'forge'),
        'password'  => env('DB_PASSWORD', ''),
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
            'strict'    => false,
        ],

    ],

    // other stuff

];

I'm using the sqlite database in memory which is a lot faster. You can't use it in functional or acceptance tests though.

And now a snippet of my tests/unit/TestCase.php. I set up the DB_DEFAULT variable which switches the database driver for each test. That way, I can run my unit/integration tests without having a separate .env.unit file.

<?php namespace UnitTests;

use Illuminate\Support\Facades\Artisan;

class TestCase extends \Illuminate\Foundation\Testing\TestCase
{

    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    {
        putenv('DB_DEFAULT=sqlite_testing');

        $app = require __DIR__ . '/../../bootstrap/app.php';

        $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();

        return $app;
    }

    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
    }

    public function tearDown()
    {
        Artisan::call('migrate:reset');
        parent::tearDown();
    }

}

Final note. As of this moment, running composer require "codeception/codeception:*" will get you the version 2.0.11. Running functional tests with Laravel 5 module will through a fatal error.

https://github.com/Codeception/Codeception/pull/1756

That will be fixed in 2.0.12, but for now you can install the latest dev version: composer require "codeception/codeception": "2.0.*@dev"

6 likes
etbal's avatar

Just a note, the environment variable for database has changed,

putenv('DB_DEFAULT=sqlite_testing');

must change to

putenv('DB_CONNECTION=sqlite_testing');
mahmoudz's avatar
  1. open the config file database.php and add the following inside the 'connections' => [
'sqlite_testing' => [
    'driver'   => 'sqlite',
    'database' => ':memory:',
    'prefix'   => '',
],

this in memory sqlite will be used for your testing

  1. open the .env file and make sure it has the following:
DB_CONNECTION=mysql
  1. open phpunit.xml and add the following inside the tag:
<env name="DB_CONNECTION" value="sqlite_testing"/>

here’s where you can add all the testing related env variables

  1. in your tests were you use a database connection use the Database Migration Trait:
use DatabaseMigrations;

for more details about the DatabaseMigrations refer to the documentation https://laravel.com/docs/5.1/testing#resetting-the-database-after-each-test

6 likes
travis-miller's avatar

Really late to the party on this one but I wanted to add a some what simpler solution should others arrive here like I did via search...

When looking at the laravel docs ( https://laravel.com/docs/5.2/configuration#environment-configuration ) I noticed a small paragraph that makes all the difference:

If the APP_ENV environment variable is set before bootstrapping the application, Laravel will attempt to load a file that matches the environment.

The key piece is before bootstrapping. So consider:

php artisan migrate --env=testing

This does in fact set the environment=testing however it does so AFTER the app has bootstrapped so it will read the .env not the .env.testing

Now consider:

APP_ENV=testing php artisan migrate

In this case APP_ENV is set BEFORE the app bootstraps so it will read .env.testing and not .env.

So, if you set your DB_NAME to something like pgsql_testing in your .env.testing and then run your migrations with the environment variable set via the command line it will all jive.

Hope it helps!

4 likes
rolly's avatar

I am using this 'env name="DB_DATABASE" value="test_db"' in the phpunit.xml file located in the root project And it works fine for me when i run phpunit from console. If u are using phpstorm, u need to set the phpunit.xml file in the preferences/php/phpunit/Test runner/ check Default configuration file and find the file phpunit.xml in the root project.

Have fun.

1 like

Please or to participate in this conversation.