Skip to main content

Introduction

Laravel provides first-class support for testing database-driven applications. You can combine database reset traits, model factories, and test-specific assertions to write fast and reliable feature tests. In most cases, start with RefreshDatabase. It keeps tests isolated while remaining faster than fully rebuilding the database every time.

Resetting the database after each test

To prevent data from one test affecting another test, use one of Laravel’s database reset traits.
<?php

use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('basic example', function () {
    $response = $this->get('/');

    $response->assertOk();
});
RefreshDatabase checks whether the database schema is already up to date. If it is, Laravel runs each test in a transaction. If it is not, Laravel runs migrations first. If you need a full reset strategy instead of transaction-based isolation, use the following traits:
TraitBehaviorWhen to use
RefreshDatabaseUses transactions if schema is current; migrates when neededDefault choice for most test suites
DatabaseMigrationsRuns migrations for each testWhen you need migration-level lifecycle behavior in every test
DatabaseTruncationTruncates tables between testsWhen transactions are not suitable and truncation fits your DB workflow

Model factories

Before asserting behavior, you often need test data. Laravel model factories provide expressive defaults for creating Eloquent models. For full factory definitions and advanced states / relationships, see Eloquent Factories.
<?php

use App\Models\User;

test('models can be instantiated', function () {
    $user = User::factory()->create();

    expect($user->exists)->toBeTrue();
});

Running seeders

Use the seed() method to populate data during tests. Without arguments, it runs DatabaseSeeder. You can also run a specific seeder class or an array of classes.
<?php

use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('orders can be created', function () {
    $this->seed();

    $this->seed(OrderStatusSeeder::class);

    $this->seed([
        OrderStatusSeeder::class,
        TransactionStatusSeeder::class,
    ]);

    // ...
});
You may also seed automatically for tests using RefreshDatabase by using attributes:
<?php

namespace Tests;

use Illuminate\Foundation\Testing\Attributes\Seed;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

#[Seed]
abstract class TestCase extends BaseTestCase
{
}
To run a specific seeder automatically, use #[Seeder(...)]:
<?php

namespace Tests\Feature;

use Database\Seeders\OrderStatusSeeder;
use Illuminate\Foundation\Testing\Attributes\Seeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

#[Seeder(OrderStatusSeeder::class)]
class OrderStatusTest extends TestCase
{
    use RefreshDatabase;
}

Available assertions

Laravel provides dedicated database assertions for both Pest and PHPUnit feature tests.

assertDatabaseCount

Assert that a table contains the expected number of records.
$this->assertDatabaseCount('users', 5);

assertDatabaseEmpty

Assert that a table contains no records.
$this->assertDatabaseEmpty('users');

assertDatabaseHas

Assert that a table contains records matching the given attributes.
$this->assertDatabaseHas('users', [
    'email' => '[email protected]',
]);

assertDatabaseMissing

Assert that a table does not contain records matching the given attributes.
$this->assertDatabaseMissing('users', [
    'email' => '[email protected]',
]);

assertSoftDeleted

Assert that the given model has been soft deleted.
$this->assertSoftDeleted($user);

assertNotSoftDeleted

Assert that the given model has not been soft deleted.
$this->assertNotSoftDeleted($user);

assertModelExists

Assert that the given model (or collection of models) exists in the database.
<?php

use App\Models\User;

$user = User::factory()->create();

$this->assertModelExists($user);

assertModelMissing

Assert that the given model (or collection of models) does not exist in the database.
<?php

use App\Models\User;

$user = User::factory()->create();
$user->delete();

$this->assertModelMissing($user);

expectsDatabaseQueryCount

Call this at the beginning of a test to assert the exact total number of database queries executed.
$this->expectsDatabaseQueryCount(5);

// Test...
Last modified on May 29, 2026