Setting up an in memory SQLite database for testing in Laravel 5.4

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Setting Up an In-Memory SQLite Database for Testing in Laravel 5.4

Developing robust end-to-end tests, especially those involving browser automation like Dusk, requires a clean and isolated testing environment. When dealing with database interactions, the temptation is often to use real databases, but this leads to data pollution, slow tests, and uniqueness constraints failing—exactly the problems you are facing. Implementing an in-memory SQLite database that resets after every test cycle is the perfect solution for this scenario.

However, getting Laravel's testing suite (PHPUnit) to recognize and utilize a custom connection defined outside of the standard setup can be tricky. As a senior developer, I can guide you through the correct architectural approach to ensure your custom SQLite setup works seamlessly within your Laravel 5.4 application.

Understanding the Challenge in Laravel Testing

Your attempt to use environment files (.env, .env.testing) and modify the database.php configuration is the right starting point. The difficulty lies in how Laravel bootstraps its service providers and config files during a PHPUnit run. By default, Laravel looks for standard database configurations. To force it to use your custom setup, you need to ensure that this configuration is loaded before any model or migration calls are executed by the test runner.

The issue you are seeing—where tests don't seem to utilize the testing database despite no errors—suggests that while your environment variables might be set for general execution, the specific mechanism Laravel uses to connect during the test bootstrap isn't being correctly overridden globally in a way PHPUnit understands.

The Robust Solution: Leveraging Database Configuration and Setup Hooks

Instead of relying solely on manipulating .env files for this deep level of testing control, we should integrate the database setup directly into your test class lifecycle, ensuring that the connection is established as :memory: specifically when running tests.

Here is how you can refine your approach to ensure PHPUnit recognizes and utilizes your in-memory SQLite instance:

1. Refine Your Database Configuration

Ensure your database.php correctly defines the custom connection. The use of :memory: for an in-memory database is key, as it ensures the entire database exists only in RAM and is discarded when the connection closes (or the script ends).

// database.php snippet
'connections' => [
    // ... other connections
    'sqlite_testing' => [
        'driver'   => 'sqlite',
        'database' => ':memory:', // This ensures an in-memory instance
        'prefix'   => '',
    ],
],

2. Control the Connection within the Test Setup

The most reliable way to force Laravel to use this specific connection during testing is to override the configuration within your test setup hooks, rather than relying solely on environment variables for this critical step. You can achieve this by setting the connection explicitly before running migrations or seeding.

In your DuskTestCase class, modify the setUp() method to explicitly tell Laravel which connection to use when it initializes its testing environment:

use Illuminate\Support\Facades\DB;
use Tests\TestCase as BaseTestCase; // Assuming this is where you extend from

abstract class DuskTestCase extends BaseTestCase
{
    /**
     * Setup the database connection for all tests.
     */
    public function setUp()
    {
        parent::setUp();

        // 1. Explicitly set the desired connection for testing
        DB::setDefaultConnection('sqlite_testing');

        // 2. Run migrations and seeding against this specific connection
        Artisan::call('migrate');
        Artisan::call('db:seed');
    }

    /**
     * Tear down the database after each test cycle.
     */
    public function tearDown()
    {
        // Resetting the state is crucial for true isolation.
        Artisan::call('migrate:reset');
        parent::tearDown();
    }
    // ... rest of your class
}

3. Managing Environment Variables for Context

While direct configuration overrides are powerful, keeping environment variables like APP_ENV=testing in place is still good practice as it signals the intended testing context to other parts of the Laravel framework. You can use your .env.testing file primarily for general application settings and let your test class handle the specific database connection setup.

For complex setups involving multiple environments, understanding how configuration files are merged (as discussed in deep dives on frameworks like those found at https://laravelcompany.com) is essential to avoid conflicts.

Conclusion

By moving the responsibility of selecting and initializing the testing database from purely environment variables to explicit calls within your test setup methods (setUp()), you gain precise control over the execution environment. This ensures that PHPUnit correctly executes the necessary Laravel commands against your desired in-memory SQLite instance, providing a clean, fast, and perfectly isolated environment for your Dusk browser tests. Remember, testing infrastructure should be explicitly defined where it is executed, which is a core principle of good software design.