DEV Community

Grant
Grant

Posted on

Speed up migrations when running Laravel tests

I'm currently doing maintenance on a two year old application. Not that old, right? Eh, sort of.

It was created using Laravel 7. I was able to upgrade to Laravel 8 and PHP 8.0, so that's great! The thing is, I'm now going test-by-test and optimizing and house cleaning. I'm also mad at Past Grant for being lazy.

The application is... big. One of my biggest I've ever built. Like 126-migration-files big. When I went to my first test, I noticed that it took forever for it to actually run the test (it failed if you were wondering). When I mean forever, I mean over 11 seconds, which might has well been 11 minutes when I'm staring at the console waiting for it to start.

I remembered when watching the keynote on Laravel 8, Taylor introduced the new feature of squashing migrations. Let's see what impact it had on my tests.

php artisan schema:dump --prune
Enter fullscreen mode Exit fullscreen mode

This command generates a file in database/schema and deletes all my migration files. Before squashing the migrations, it was taking 11.031 seconds according to well placed Ray call in the RefreshDatabase trait:

protected function refreshTestDatabase()
{
    ray()->measure('migrating');
    if (! RefreshDatabaseState::$migrated) {
        $this->artisan('migrate:fresh', $this->migrateFreshUsing());

        $this->app[Kernel::class]->setArtisan(null);

        RefreshDatabaseState::$migrated = true;
    }
    ray()->measure('migrating');

    $this->beginDatabaseTransaction();
}
Enter fullscreen mode Exit fullscreen mode

After squashing, it took only 1.396 seconds. That's almost a 90% decrease in time! Now I can spend the next several days fixing all my terrible tests, but they'll at least run faster.

Discussion (0)