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

FrankPeters's avatar

[L5] Behat testing environment

I'm currently writing some Behat functional feature testst that interact with the database. However I can't get it to use the testing environment database.

I'm using a .env:

APP_ENV=local
APP_KEY=***
DB_USERNAME=homestead
DB_PASSWORD=secret

And this is the LaravelFeatureContext:

/**
 * Defines application features from the specific context.
 */
class LaravelFeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
    /**
     * @static
     * @beforeSuite
     */
    public static function bootstrapLaravel()
    {
        $unitTesting = true;
        $testEnvironment = 'testing';

        $app = require_once __DIR__ . '/../../bootstrap/start.php';
        $app->boot();

        Artisan::call('migrate:refresh');
        Artisan::call('db:seed');
    }
{

I have also tried things like:

Dotenv::setEnvironmentVariable('APP_ENV', 'testing');

On various lines in above method. But to no avail. Anyone know how to get it to work?

Edit: I have to say that it does seem to do something as it did change the database.sqllite under storage according to VCS. But it still hits my MySQL DB during the actual testing.

0 likes
1 reply
FrankPeters's avatar
FrankPeters
OP
Best Answer
Level 1

Ok, I seem to have gotten a solution! This is my LaravelFeatureContext now:

/**
 * Defines application features from the specific context.
 */
class LaravelFeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{

    /**
     * @static
     * @beforeSuite
     */
    public static function bootstrapLaravel()
    {

        // Override environment when booting Laravel
        Dotenv::setEnvironmentVariable('APP_ENV', 'functional');

        require_once __DIR__.'/../../bootstrap/start.php';

        Mail::pretend(true);

        // Refresh database for the functional environment
        Artisan::call('migrate:refresh', array('--env' => 'functional'));
        Artisan::call('db:seed', array('--env' => 'functional'));

    }
}

This will use the Dotenv override method. However I still need to manually set the environment when doing the migrate:refresh and db:seed because otherwise the default environment gets fired.

Further more I've set up Homestead to create a .test URL as well by modifying the serve.sh:

block="server {
    listen 80;
    server_name $1 ${1/.dev/.test};
    root $2;

    [...]
}

And I've updated the environment detection for Laravel like so:

$env = $app->detectEnvironment(function()
{
    // Detect functional testing env
    if(isset($_SERVER['HTTP_HOST']) && ends_with($_SERVER['HTTP_HOST'], '.test'))
    {
        return 'functional';
    }

 return getenv('APP_ENV') ?: 'production';
});

Please or to participate in this conversation.