> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Pruebas de base de datos

> Cómo escribir pruebas de base de datos eficientes en Laravel utilizando RefreshDatabase, seeders, factorías y aserciones específicas.

## 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.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use Illuminate\Foundation\Testing\RefreshDatabase;

  uses(RefreshDatabase::class);

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

      $response->assertOk();
  });
  ```

  ```php PHPUnit theme={null}
  <?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();
      }
  }
  ```
</CodeGroup>

`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.

```mermaid theme={null}
flowchart TD
    A[Inicio de la prueba con RefreshDatabase] --> B{¿El esquema está al día?}
    B -- Sí --> C[Ejecutar dentro de una transacción de BD]
    B -- No --> D[Ejecutar migraciones]
    D --> E[Ejecutar la prueba]
    C --> E[Ejecutar la prueba]
    E --> F[Rollback / reinicio del estado]
```

Si prefieres un reinicio completo en lugar de la vía transaccional, dispones de los siguientes traits.

| Trait                | Comportamiento                                                        | Cuándo usarlo                                                    |
| -------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `RefreshDatabase`    | Transacción si el esquema está al día; solo migra cuando es necesario | Suele ser la primera opción                                      |
| `DatabaseMigrations` | Ejecuta las migraciones en cada prueba                                | Cuando quieres pasar por el ciclo completo de migración cada vez |
| `DatabaseTruncation` | Trunca las tablas para reiniciarlas                                   | Cuando 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](/es/eloquent-factories).

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Models\User;

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

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

  ```php PHPUnit theme={null}
  <?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);
      }
  }
  ```
</CodeGroup>

## 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).

<CodeGroup>
  ```php Pest theme={null}
  <?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 PHPUnit theme={null}
  <?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,
          ]);

          // ...
      }
  }
  ```
</CodeGroup>

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 theme={null}
<?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 theme={null}
<?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.

<CodeGroup>
  ```php Pest theme={null}
  $this->assertDatabaseCount('users', 5);
  ```

  ```php PHPUnit theme={null}
  $this->assertDatabaseCount('users', 5);
  ```
</CodeGroup>

### `assertDatabaseEmpty`

Comprueba que la tabla está vacía.

<CodeGroup>
  ```php Pest theme={null}
  $this->assertDatabaseEmpty('users');
  ```

  ```php PHPUnit theme={null}
  $this->assertDatabaseEmpty('users');
  ```
</CodeGroup>

### `assertDatabaseHas`

Comprueba que existe un registro que cumple las condiciones indicadas.

<CodeGroup>
  ```php Pest theme={null}
  $this->assertDatabaseHas('users', [
      'email' => 'sally@example.com',
  ]);
  ```

  ```php PHPUnit theme={null}
  $this->assertDatabaseHas('users', [
      'email' => 'sally@example.com',
  ]);
  ```
</CodeGroup>

### `assertDatabaseMissing`

Comprueba que no existe ningún registro que cumpla las condiciones indicadas.

<CodeGroup>
  ```php Pest theme={null}
  $this->assertDatabaseMissing('users', [
      'email' => 'sally@example.com',
  ]);
  ```

  ```php PHPUnit theme={null}
  $this->assertDatabaseMissing('users', [
      'email' => 'sally@example.com',
  ]);
  ```
</CodeGroup>

### `assertSoftDeleted`

Comprueba que el modelo Eloquent indicado ha sido eliminado con soft delete.

<CodeGroup>
  ```php Pest theme={null}
  $this->assertSoftDeleted($user);
  ```

  ```php PHPUnit theme={null}
  $this->assertSoftDeleted($user);
  ```
</CodeGroup>

### `assertNotSoftDeleted`

Comprueba que el modelo Eloquent indicado no ha sido eliminado con soft delete.

<CodeGroup>
  ```php Pest theme={null}
  $this->assertNotSoftDeleted($user);
  ```

  ```php PHPUnit theme={null}
  $this->assertNotSoftDeleted($user);
  ```
</CodeGroup>

### `assertModelExists`

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

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Models\User;

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

  $this->assertModelExists($user);
  ```

  ```php PHPUnit theme={null}
  <?php

  use App\Models\User;

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

  $this->assertModelExists($user);
  ```
</CodeGroup>

### `assertModelMissing`

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

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Models\User;

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

  $this->assertModelMissing($user);
  ```

  ```php PHPUnit theme={null}
  <?php

  use App\Models\User;

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

  $this->assertModelMissing($user);
  ```
</CodeGroup>

### `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.

<CodeGroup>
  ```php Pest theme={null}
  $this->expectsDatabaseQueryCount(5);

  // Test...
  ```

  ```php PHPUnit theme={null}
  $this->expectsDatabaseQueryCount(5);

  // Test...
  ```
</CodeGroup>


## Related topics

- [Seeding de base de datos](/es/seeding.md)
- [Configuración de la base de datos](/es/database.md)
- [Migraciones de base de datos](/es/migrations.md)
- [Pruebas de navegador (Dusk)](/es/dusk.md)
- [Laravel Sail](/es/sail.md)
