BACK
Laravel / Testing

Speed Up Test Suites with the LazilyRefreshDatabase Trait

Punyapal Shah 1 min read
edit this tip

Use LazilyRefreshDatabase instead of RefreshDatabase to run database transactions only for tests that actually touch the database.

When running large test suites, the traditional RefreshDatabase trait migrates and resets database transactions before every test, even for pure unit tests that only test formatting or calculations without touching SQL.

LazilyRefreshDatabase defers database initialization until a query is executed.

Using LazilyRefreshDatabase in Tests

namespace Tests\Feature;

use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
use Tests\TestCase;

class UserFeatureTest extends TestCase
{
    use LazilyRefreshDatabase;

    test('calculates user discount percentage', function () {
        // Pure calculation: No database query executed, database setup is skipped!
        $discount = (new Calculator)->discount(100, 20);
        expect($discount)->toBe(80);
    });

    test('creates user record in database', function () {
        // First database query triggers lazy transaction setup automatically
        $user = User::factory()->create();
        $this->assertModelExists($user);
    });
}

Summary

  • Defer database connection setup until the first SQL query executes.
  • Significantly accelerates test suite runtime in hybrid unit/feature suites.
  • Drop-in replacement for RefreshDatabase.

Related Tips

View all tips →

// Got a tip in mind? Contributions are always welcome