SQLite Testing And Quick Start Guide for Laravel

Automated Testing

When testing with Laravel and SQLite, you'll have to make small adjustments to your configuration to get it working perfectly. Here are some of them.

Enabling SQLite in phpunit.xml

In older versions of Laravel, you'll have to uncomment `DB_CONNECTION` AND `DB_DATABASE`.

<phpunit>
    ...
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="APP_MAINTENANCE_DRIVER" value="file"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_STORE" value="array"/>
        <!-- <env name="DB_CONNECTION" value="sqlite"/> -->
        <!-- <env name="DB_DATABASE" value=":memory:"/> -->
        <env name="MAIL_MAILER" value="array"/>
        <env name="PULSE_ENABLED" value="false"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="TELESCOPE_ENABLED" value="false"/>
    </php>
</phpunit>
lang-php

Add RefreshDatabase Trait

For migrations to work out of the box, you'll need to add the `RefreshDatabase` trait to the base `TestCase`:

use Illuminate\Foundation\Testing\RefreshDatabase;

abstract class TestCase extends BaseTestCase
{
    use RefreshDatabase;
}
lang-php

Foreign Key Check Issues

If you have foreign key migration commands, such as this:

// Disable foreign key constraints
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
lang-php

You'll end up with errors like these:

SQLSTATE[HY000]: General error: 1 near "SET": syntax error (Connection: sqlite, SQL: SET FOREIGN_KEY_CHECKS = 0)
lang-bash

Wrap these statements like so:

if (DB::connection()->getDriverName() !== 'sqlite')
{            
    // Disable foreign key constraints for sqlite only
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');        
}
lang-php

Herd Email Setup

Herd has a powerful email viewer and it's sometimes more handy to have this away from Ray. For Herd email, change this line in phpunix.xml from:

<env name="MAIL_MAILER" value="array"/>
lang-bash

to:

<env name="MAIL_MAILER" value="smtp"/>
<env name="MAIL_HOST" value="127.0.0.1"/>
<env name="MAIL_PORT" value="2525"/>
<env name="MAIL_USERNAME" value="Project Name"/>
lang-bash

Be careful though, because if you have GitHub workflows there won't be a mail server running on port 2525, so you may have test failures.

Scout Redis Connection Refused

If your automated tests work on `localhost`, but fails at GitHub workflows or your colleagues' computer, you might be suffering from a deep dependency chain all the way to Redis. The thing is Scout works better with Redis and queueing so if your models have the Searchable trait and your entire test suite starts to fail randomly, it's most likely that the end-system doesn't have Redis installed.

RedisException Connection refused

So unless you are actually doing Redis testing, a quick fix would is this:

class TestCase extends BaseTestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        // first include all the normal setUp operations
        parent::setUp();

        // Disable Scout to avoid Redis dependencies during testing
        config(['scout.driver' => 'null']);
        config(['scout.queue' => false]);
lang-php