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 searchAccording 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: testingAgain, 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.