Saltar al contenido principal

Introducción

Laravel incluye herramientas listas para probar de forma segura y rápida las funcionalidades que dependen de la base de datos. Combinando el trait de reinicio de la base de datos, las factorías de modelos, los seeders y las aserciones específicas puedes escribir pruebas robustas y difíciles de romper. Lo habitual es empezar con RefreshDatabase, que en la mayoría de los casos mantiene el aislamiento de las pruebas más rápido que un reset completo.

Reiniciar la base de datos después de cada prueba

Para que los datos de una prueba no afecten a la siguiente, utiliza el trait de reinicio de base de datos que ofrece Laravel.
<?php

use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('ejemplo básico', function () {
    $response = $this->get('/');

    $response->assertOk();
});
<?php

namespace Tests\Feature;

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

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    public function test_basic_example(): void
    {
        $response = $this->get('/');

        $response->assertOk();
    }
}
RefreshDatabase comprueba si el esquema está al día. Si lo está, ejecuta la prueba dentro de una transacción; si no, ejecuta primero las migraciones. Si prefieres un reinicio completo en lugar de la vía transaccional, dispones de los siguientes traits.
TraitComportamientoCuándo usarlo
RefreshDatabaseTransacción si el esquema está al día; solo migra cuando es necesarioSuele ser la primera opción
DatabaseMigrationsEjecuta las migraciones en cada pruebaCuando quieres pasar por el ciclo completo de migración cada vez
DatabaseTruncationTrunca las tablas para reiniciarlasCuando la transacción no es adecuada y quieres borrarlo todo

Factorías de modelos

Para preparar datos antes de una prueba, las factorías de modelos permiten crear modelos Eloquent con muy poco código. Consulta los detalles sobre definición de factorías, state y relaciones en la sección de factorías de Eloquent.
<?php

use App\Models\User;

test('se puede generar un modelo', function () {
    $user = User::factory()->create();

    expect($user->exists)->toBeTrue();
});
<?php

namespace Tests\Feature;

use App\Models\User;
use Tests\TestCase;

class UserFactoryTest extends TestCase
{
    public function test_models_can_be_instantiated(): void
    {
        $user = User::factory()->create();

        $this->assertTrue($user->exists);
    }
}

Ejecutar seeders

Cuando necesites cargar datos durante una prueba, utiliza seed(). Sin argumentos ejecuta DatabaseSeeder; con argumentos, un seeder concreto (o un array de ellos).
<?php

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

uses(RefreshDatabase::class);

test('se pueden crear pedidos', function () {
    $this->seed();

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

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

    // ...
});
<?php

namespace Tests\Feature;

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

class OrderTest extends TestCase
{
    use RefreshDatabase;

    public function test_orders_can_be_created(): void
    {
        $this->seed();

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

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

        // ...
    }
}
Si quieres que todas las pruebas que usan RefreshDatabase ejecuten un seed automáticamente, añade el atributo #[Seed] a la clase base de tus tests.
<?php

namespace Tests;

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

#[Seed]
abstract class TestCase extends BaseTestCase
{
}
Para ejecutar automáticamente un seeder específico, utiliza #[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;
}

Aserciones disponibles

Laravel ofrece un conjunto de aserciones específicas para bases de datos que puedes utilizar tanto con Pest como con PHPUnit.

assertDatabaseCount

Comprueba que el número de registros de una tabla coincide con el valor esperado.
$this->assertDatabaseCount('users', 5);
$this->assertDatabaseCount('users', 5);

assertDatabaseEmpty

Comprueba que la tabla está vacía.
$this->assertDatabaseEmpty('users');
$this->assertDatabaseEmpty('users');

assertDatabaseHas

Comprueba que existe un registro que cumple las condiciones indicadas.
$this->assertDatabaseHas('users', [
    'email' => '[email protected]',
]);
$this->assertDatabaseHas('users', [
    'email' => '[email protected]',
]);

assertDatabaseMissing

Comprueba que no existe ningún registro que cumpla las condiciones indicadas.
$this->assertDatabaseMissing('users', [
    'email' => '[email protected]',
]);
$this->assertDatabaseMissing('users', [
    'email' => '[email protected]',
]);

assertSoftDeleted

Comprueba que el modelo Eloquent indicado ha sido eliminado con soft delete.
$this->assertSoftDeleted($user);
$this->assertSoftDeleted($user);

assertNotSoftDeleted

Comprueba que el modelo Eloquent indicado no ha sido eliminado con soft delete.
$this->assertNotSoftDeleted($user);
$this->assertNotSoftDeleted($user);

assertModelExists

Comprueba que un modelo (o una colección de modelos) existe en la base de datos.
<?php

use App\Models\User;

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

$this->assertModelExists($user);
<?php

use App\Models\User;

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

$this->assertModelExists($user);

assertModelMissing

Comprueba que un modelo (o una colección de modelos) no existe en la base de datos.
<?php

use App\Models\User;

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

$this->assertModelMissing($user);
<?php

use App\Models\User;

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

$this->assertModelMissing($user);

expectsDatabaseQueryCount

Al comienzo de la prueba puedes especificar de forma estricta el número total de consultas a la base de datos que se deben ejecutar. Si el número real no coincide, la prueba falla.
$this->expectsDatabaseQueryCount(5);

// Test...
$this->expectsDatabaseQueryCount(5);

// Test...
Última modificación el 13 de julio de 2026