If you don’t use SQLite in production, you shouldn’t use it in testing or CI/CD either.
This is one of the reasons why I switched from using the SQLite + :memory:
combo for my Laravel + Pest testing:
// migration
Schema::create('segments', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->unique();
$table->string('name')->unique();
$table->timestamps();
$table->softDeletes();
});
// route
Route::get('/segments', function (Request $request) {
$value = $request->input('search');
return Segment::query()
->when($value, function (Builder $query, string $value) {
$query->where('namexxx', 'LIKE', "%$value%")
})
->get();
});
// test
it('can search', function () {
get(uri: '/segment?search=awesome')
->assertStatus(status: 200);
});
Notice how I intentionally wrote the wrong field name in the search query. Surprisingly, my tests still pass. It should throw an \Illuminate\Database\QueryException
as it would in a browser.
PASS Tests\Feature\Segments\IndexControllerTest
✓ it can search
According to the SQLite documentation:
If a keyword in double quotes (ex: “key” or “glob”) is used in a context where it cannot be resolved to an identifier but where a string literal is allowed, then the token is understood to be a string literal instead of an identifier.
So what we need to do is to use real database for testing, specifically MariaDB in my case. You’ll need to modify your phpunit.xml
first.
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_HOST" value="testing-host"/>
<env name="DB_DATABASE" value="testing-db"/>
<env name="DB_USERNAME" value="testing-username"/>
<env name="DB_PASSWORD" value="testing-password"/>
Adjust this configuration according to your needs. If left blank, Laravel will fallback to defaults, such as DB_USERNAME
being forge
.
Next, modify your GitHub action. Add your preferred database image into services
, next to container
:
jobs:
pest:
runs-on: ubuntu-latest
container:
image: serversideup/php:8.1-cli
services:
mariadb-testing:
image: mariadb:10.11
env:
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: true
MARIADB_DATABASE: testing
Again, adjust the env
settings to match your phpunit.xml
.
That’s it, now your github action will run tests against a real database instead SQLite.