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

olimorris's avatar

Setting testing environment variables

Hi All,

I specify my environment variables in phpunit.xml and have created a .env.testing file.

However when I run:

php artisan migrate --env="testing"

I get:

Nothing to migrate

How I can I make Laravel load my test variables?

0 likes
12 replies
uxweb's avatar

Are you using Laravel 4 or Laravel 5?

olimorris's avatar

Laravel 5. So I have my .env setup for local work.

michaeldyrynda's avatar

How have you specified the environment variables in phpunit.xml? Show us the file. Laravel 5 doesn't use .env.* files (with exception to phpspec, I believe), you should specify all your testing environment variables within the relevant section in the phpunit.xml file.

olimorris's avatar

Section from my PHPUnit.xml file:

 <testsuites>
        <testsuite name="Application Test Suite">
            <directory>./tests/phpunit/</directory>
        </testsuite>
    </testsuites>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="DB_TYPE" value="mysql"/>
        <env name="DB_HOST" value="localhost"/>
        <env name="DB_DATABASE" value="testing"/>
        <env name="DB_USERNAME" value="homestead"/>
        <env name="DB_PASSWORD" value="secret"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
    </php>

and my .env:

APP_ENV=local
APP_DEBUG=true
APP_KEY=SOMEKEY

DB_TYPE=mysql
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
3 likes
olimorris's avatar

Just wondered how people are getting around this in Laravel 5?

SachinAgarwal's avatar

@olimorris I had same problem, Seems like --env option is having no effect.
I solved it like this:
when ever I need to migrate the testing database, I just change the values of the database configurations in .env and migrate it, and then after migration, change the config to original database config.
I know its not the proper solution, But i did not get any proper solution either. So I do this way,

bobbybouwmann's avatar
Level 88

This is my setup!

I create a .env.testing file where I keep all my settings for my database stuff like the file below. Note that I didn't include the database credentials since I use sqlite for testing so you don't need that stuff (it's much faster then mysql)

.env.testing

APP_ENV=testing
APP_DEBUG=true
APP_KEY=TcqTXRLRsXVJeEgbiAgk8NwtEvQTiIbc

DB_DEFAULT=sqlite_testing

CACHE_DRIVER=file
SESSION_DRIVER=file

I updated my config/database.php file like this. Node that I specified tho sqlite_testing variables. You can either use a sqlite database or use memory for testing. Memory is even faster. I only use memory for unit testing since I want to test my functional tests and integration tests on a real database like sqlite or mysql.

config/database.php

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

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

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

    // other connections

],

Then I updated my functional and unit tests suites.yml files like so

tests/functional.suite.yml

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

tests/unit.suite.yml

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

Now it's important that if you use the sqlite database you need to migrate it as well! Since we did set it up in our config it's really easy to migrate it. We first need to create a file called testing.sqlite in the storage directory. Now we can migrate that database, like we specified in the config

php artisan migrate --database=sqlite_testing

This should get you up and running

6 likes
olimorris's avatar

Thanks @blackbird

In the end I just did:

php artisan migrate --database="testing"

and prompt CodeCeption and Behat to load my .env.testing file. I would like to see Laravel 5 automatically load environment variables from a .env.testing file when any tests are running.

dcranford's avatar

You can try using:

APP_ENV=testing php artisan migrate

I believe that should set the APP_ENV parameter before artisan runs so that it pulls in the desired environment

tylerhelix's avatar

For Laravel 5, I created a custom Artisan loader artisan-env.php, which allows you to select which .env file to use. Pretty simple.

#!/usr/bin/env php
<?php
/*
 * This custom artisan loader allows you to specify which .env file to use.
 * Execute it like you would a normal command, but pass the path to the .env file that you wish to use as the first
 * parameter. For example:
 *
 * php artisan .env.test migrate:refresh
 */

require __DIR__.'/bootstrap/autoload.php';

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

/*
 * Extract the second argv parameter and attempt to load it as the .env file
 */
$argv = $_SERVER['argv'];
$cmd = $argv[0];
$envFile = isset($argv[1]) ? $argv[1] : null;
if(!$envFile) {
    exit("Usage: artisan envFile [artisan params]\n");
}
if(!file_exists($envFile)) {
    exit(".env file: \"$envFile\" not found.\n");
}

$kernel = $app->make('Illuminate\Contracts\Console\Kernel');
$app->loadEnvironmentFrom($envFile);

/*
 * Remove the 2nd param (.env file) such that the standard artisan / kernel process can function like normal
 */
$args = array_merge([$cmd], array_slice($argv, 2));

$status = $kernel->handle(
    $input = new Symfony\Component\Console\Input\ArgvInput($args),
    new Symfony\Component\Console\Output\ConsoleOutput
);


$kernel->terminate($input, $status);

exit($status);
coreysan's avatar

I was able to get this working by doing the following:

i) Create a separate mysql database and user with privs in the mysql repl:

CREATE DATABASE app_test;
CREATE USER app_test@localhost IDENTIFIED BY 'password';
GRANT ALL ON app_test.* TO app_test@localhost;

ii) In database.php, add an entry to the connections array:

return [

   //... other details ...

    'connections' => [

        // ... some connections...

        'mysql_test' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
        ],
        // ... more connections

// ... more details ...

iii) Copy your .env to a separate env file named .env.testing (must match exactly).

iv) In .env.testing, replace the following DB details:

DB_CONNECTION=mysql_test
DB_DEFAULT=mysql_test
DB_DATABASE=app_test
DB_USERNAME=app_test
DB_PASSWORD=password

v) Migrate the test db: php artisan migrate --env=testing

2 likes

Please or to participate in this conversation.