Building a Database

Adapt creates and removes databases for your tests as needed. You don't need to create empty ones yourself beforehand.

Unless you choose otherwise, Adapt builds a database for your default database connection.

Structure and Data

Adapt performs the following steps when building a database: Imports, Migrations and Seeders. Each step is optional.

Imports

You can tell Adapt to import custom database sql-dump file/s before your migrations and seeders run.

TIP

This is an alternative to Laravel's migration squashingopen in new window feature, which you may want to use instead.

You can generate a sql-dump file using MySQL's mysqldump commandopen in new window, or PostgreSQL's pg_dump commandopen in new window.

To import your file, put it in your filesystem, and add it to Adapt's build_sources.initial_imports config setting. You can also specify it per-test by adding the $initialImports property to your test-classes.

⚙️ See configuration
<?php
// config/code_distortion.adapt.php

return ['build_sources' => [
       'initial_imports' => [
           'mysql' => ['database/dumps/mysql/db.sql',],
           'pgsql' => ['database/dumps/pgsql/db.sql',],
           'sqlite' => ['database/dumps/sqlite/db.sqlite'], // NOTE: SQLite files are simply copied
       ],],];







 
 
 





or

<?php
// tests/Feature/MyFeatureTest.php

use CodeDistortion\Adapt\AdaptDatabase;
use Tests\TestCase;

class MyFeatureTest extends TestCase
{
    use AdaptDatabase;

    protected array $initialImports = [
        'mysql' => ['database/dumps/mysql/db.sql',],
        'pgsql' => ['database/dumps/pgsql/db.sql',],
        'sqlite' => ['database/dumps/sqlite/db.sqlite'], // SQLite files are simply copied
    ];}











 
 
 




Any remaining migrations will be run in the next step, after the import.

NOTE

SQLite database files aren't imported, they're simply copied, which is quite quick.

The imports feature isn't supported for SQLite :memory: databases.

Migrations

Most likely you'll want your migrationsopen in new window to be run when building your database.

Migrations are turned on by default. You can turn them off by changing Adapt's build_sources.migrations config setting, or by adding the $migrations property to your test-classes.

Laravel's normal migration directory /database/migrations is used by default, but you can specify another if you like.

⚙️ See configuration
<?php
// config/code_distortion.adapt.php

return ['build_sources' => ['migrations' => true, // or false
//      or
//      'migrations' => 'path/to/migrations',],];







 
 
 




or

<?php
// tests/Feature/MyFeatureTest.php

use CodeDistortion\Adapt\AdaptDatabase;
use Tests\TestCase;

class MyFeatureTest extends TestCase
{
    use AdaptDatabase;

    protected bool|string $migrations = true; // or false
//  or
//  protected bool|string $migrations = 'path/to/migrations';}










 
 
 



Adapt uses Laravel's normal migration functionality behind-the-scenes to run your migrations.

Seeders

Seedersopen in new window can be used to populate the database with particular data, ready for your tests to use.

When Adapt runs your seeders (instead of you running them yourself within your tests), this data is included in Adapt's caching mechanisms. This saves them from needing to be run each time.

It's up to you about whether this is a good idea. If you build a custom set of test-data that's shared between your tests, those tests become reliant on that data. Any changes to this data may break your tests unexpectedly, including when adding new data.

If you have a common set of standard data that always needs to exist, this would be a good situation to use this in.

You can choose which seeder/s to run by setting the build_sources.seeders config setting. You can also pick different seeders for different tests by adding the $seeders property to your test-classes.

⚙️ See configuration
<?php
// config/code_distortion.adapt.php

return ['build_sources' => ['seeders' => 'SomeDatabaseSeeder', // or ''
//      or
//      'seeders' => ['SomeDatabaseSeeder', 'SomeOtherDatabaseSeeder'], // or []
   ],];







 
 
 



or

<?php
// tests/Feature/MyFeatureTest.php

use CodeDistortion\Adapt\AdaptDatabase;
use Tests\TestCase;

class MyFeatureTest extends TestCase
{
    use AdaptDatabase;

    protected string|array $seeders = 'SomeDatabaseSeeder'; // or ''
//  or
//  protected string|array $seeders = ['SomeDatabaseSeeder', 'SomeOtherDatabaseSeeder']; // or []}










 
 
 



Adapt uses Laravel's normal seeder functionality behind-the-scenes to run your seeders.

Adapt will respect Laravel's $seed and $seeder propertiesopen in new window if you happen to use them.

NOTE

Seeders are only run if initial-imports or migrations are enabled.

Building Extra Databases

If your project uses more than one database, Adapt can build them for your tests too.

To create more databases, add the databaseInit() method to your test-class. Inside it, make a call to $this->prepareConnection($connection); to prepare another database. You can do this for as many connections as you need.

Each call will give you a new DatabaseDefinition object that you can configure. These are initially primed with your configuration settings.

A $database parameter is passed to your databaseInit() method. This is the DatabaseDefinition object Adapt uses to build your default connection's database.

⚙️ See configuration
<?php
// tests/Feature/MyFeatureTest.php

use CodeDistortion\Adapt\DatabaseDefinition;
use CodeDistortion\Adapt\AdaptDatabase;
use Tests\TestCase;

class MyFeatureTest extends TestCase
{
    use AdaptDatabase;

    protected function databaseInit(DatabaseDefinition $database): void
    {
        $initialImports =  [
            'mysql' => ['database/dumps/mysql/db.sql'],
            'pgsql' => ['database/dumps/pgsql/db.sql'],
            'sqlite' => ['database/dumps/sqlite/db.sqlite'], // SQLite files are simply copied
        ];

        // the DatabaseDefinition $database is pre-configured to match your config settings
        // for the "default" database connection
        // you can override them with any of the following…
        $database
            ->connection('primary') // specify another connection to build a db for
            ->initialImports($initialImports) // or ->noInitialImports()
            ->migrations() // or ->migrations('database/other_migrations') or ->noMigrations()
            ->seeders(['DatabaseSeeder']) // or ->noSeeders()
            ->isABrowserTest() // or ->isNotABrowserTest()
            ->transaction() // or ->noTransaction()
            ->journal() // or ->noJournal()
            ->snapshots('!afterSeeders') // or ->noSnapshots()
            ->remoteBuildUrl('https://...') // or ->noRemoteBuildUrl()
            ->forceRebuild() // or ->dontForceRebuild()
            ->makeDefault(); // make the "default" Laravel connection point to this connection

        // you can create a database for another connection
        $connection = 'secondary';
        $database2 = $this->prepareConnection($connection);
        $database2
            ->initialImports($initialImports); // or ->noInitialImports()
            // etc …
    }}

// you can then use these database connections somewhere inside a test
DB::connection('primary')->select();
DB::connection('secondary')->select();











 

























 











TIP

You might like to share your databaseInit() method between tests by adding it to a trait or parent test-class.

Rebuilding Your Database

You don't need to rebuild your database when you update your migrations, seeders or factories. Adapt detects these changes, and rebuilds them automatically.

The directories listed in the cache_invalidation.locations config setting are inspected for changes:

/database/migrations
/database/seeders
/database/factories
⚙️ See configuration
<?php
// config/code_distortion.adapt.php

return ['cache_invalidation' => ['locations' => [
            database_path('migrations'),
            database_path('seeders'), // Laravel 8 and after
//          database_path('seeds'), // before Laravel 8
            database_path('factories'),
//          'some/other/path',
        ],],];








 
 
 
 
 





TIP

If you add initial-imports, it would be a good idea to add these here as well. This way, changes to those will be detected as well.

After detecting changes, "old" databases will be marked as stale. These will be removed automatically after a little while.

Disabling Databases

You can tell Adapt to skip the database building process altogether. This might sound strange for a package whose purpose is to build databases. But it allows for other functionality to still be used.

You might wish to do this if your project doesn't have a database, and you'd still like to run your browser tests in parallel.

Database building is on by default. To turn it off, change Adapt's build_databases config setting. Or you can add the $buildDatabases property to your test-classes.

⚙️ See configuration
<?php
// config/code_distortion.adapt.php

return ['build_databases' => true, // or false];





 


or

<?php
// tests/Feature/MyFeatureTest.php
 
use CodeDistortion\Adapt\AdaptDatabase;
use Tests\TestCase;
 
class MyFeatureTest extends TestCase
{
    use AdaptDatabase;

    protected bool $buildDatabases = true; // or false}