Certainly, let's address your testing setup for multiple databases in Laravel 12 + Pest:
Core Issues
- Database not created for tests (MySQL):
Laravel'sRefreshDatabase/DatabaseMigrationstraits ensure the default database is migrated and refreshed for tests. They do not migrate/refresh secondary databases automatically. - SQLite in-memory works for default, not for other connections:
When switching to SQLite-in-memory, migrations only apply to the default connection, unless you explicitly target others.
Solution Steps:
1. Explicitly Run Migrations on Both Databases During Tests
You'll need to make sure migrations for both databases are executed during testing. Here’s how:
a) In your Pest/Laravel test, update the setUp method:
beforeEach(function () {
// Run migrations for the default connection (usually 'mysql')
$this->artisan('migrate', ['--database' => 'mysql', '--path' => '/database/migrations']);
// Run migrations for the second connection
$this->artisan('migrate', [
'--database' => 'db1', // your second connection name
'--path' => '/database/migrations_db1', // path to db1 migrations, adjust if needed
]);
});
- Make sure your migrations for
db1are in a separate directory (e.g./database/migrations_db1), or you may need to repeat'--path'for each migration file.
b) For in-memory SQLite
If using SQLite, ensure you have these settings in your .env.testing:
DB_CONNECTION=sqlite
DB_DATABASE=:memory:
DB1_CONNECTION=sqlite
DB1_DATABASE=:memory:
And in config/database.php, ensure your secondary connection (db1) can read from the test .env.testing:
'db1' => [
'driver' => env('DB1_CONNECTION', 'mysql'),
'database' => env('DB1_DATABASE', 'database_db1'),
// Other settings...
],
2. Always Specify Connection on Models
Continue using:
protected $connection = 'db1';
on models that use the secondary database.
3. Database Truncation / Refresh
When using RefreshDatabase trait, it only refreshes the default connection. To refresh/truncate tables on the second connection, add in your test:
use Illuminate\Support\Facades\DB;
beforeEach(function () {
// ...
DB::connection('db1')->table('your_table')->truncate();
});
Or run migrate:refresh for both.
4. Other Gotchas
- When using MySQL, make sure your MySQL user has privilege to create databases. Otherwise, Laravel cannot create the testing database and will fail.
- Consider setting up a separate database per connection just for tests (e.g.,
testing_db,testing_db1) and configuring those in.env.testing.
Summary
- Run migrations for each connection used in your tests.
- Ensure
.env.testingandconfig/database.phpare configured to point each connection to proper test DBs. - If using SQLite, you can use in-memory for both, but each connection must target
:memory:or its own sqlite file. - If using MySQL, make sure the test runner database user has privileges to create databases.
Example test setup
beforeEach(function () {
// Migrate main database
$this->artisan('migrate', ['--database' => 'mysql']);
// Migrate db1
$this->artisan('migrate', ['--database' => 'db1', '--path' => '/database/migrations_db1']);
});
Let me know if you need example database config or specifics on paths/setup!