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

# Test del database

> Come scrivere test DB in Laravel in modo efficiente con RefreshDatabase, seeder, factory e asserzioni dedicate

## Introduzione

Laravel include di serie i meccanismi per testare in modo sicuro e veloce le funzionalità che usano il database. Combinando i trait per il reset del database, le model factory, i seeder e le asserzioni dedicate crei test difficili da rompere.

Il punto di partenza è `RefreshDatabase`. Nella maggior parte dei casi mantiene l'indipendenza dei test più rapidamente di un reset completo.

## Reset del database dopo ogni test

Per evitare che i dati di un test influenzino il successivo, usa i trait di reset del database.

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

  use Illuminate\Foundation\Testing\RefreshDatabase;

  uses(RefreshDatabase::class);

  test('esempio base', 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` verifica se lo schema è aggiornato. Se lo è, esegue il test in una transazione; se no, esegue prima le migration.

```mermaid theme={null}
flowchart TD
    A[Inizio del test con RefreshDatabase] --> B{Schema aggiornato?}
    B -- Sì --> C[Esecuzione in una transazione DB]
    B -- No --> D[Esecuzione delle migration]
    D --> E[Esecuzione del test]
    C --> E[Esecuzione del test]
    E --> F[Rollback / reset dello stato]
```

Se preferisci un reset completo ogni volta anziché la transazione, usa questi trait.

| Trait                | Comportamento                                                      | Quando usarlo                                                           |
| -------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| `RefreshDatabase`    | Transazione se lo schema è aggiornato; migration solo quando serve | Prima scelta di default                                                 |
| `DatabaseMigrations` | Esegue le migration a ogni test                                    | Se vuoi passare per l'intero ciclo di migration ogni volta              |
| `DatabaseTruncation` | Fa TRUNCATE delle tabelle                                          | Se le transazioni non sono adatte al tuo ambiente e vuoi svuotare tutto |

## Model factory

Per preparare dati prima di un test, con le model factory generi modelli Eloquent in modo conciso.

Per dettagli su definizioni, state e relazioni consulta [Factory Eloquent](/it/eloquent-factories).

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

  use App\Models\User;

  test('è possibile creare modelli', 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>

## Esecuzione dei seeder

Per inserire dati durante il test usa `seed()`. Senza argomenti esegue `DatabaseSeeder`; con un argomento esegue un seeder specifico (o un array).

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

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

  uses(RefreshDatabase::class);

  test('è possibile creare ordini', 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>

Per seedare automaticamente in tutti i test che usano `RefreshDatabase`, aggiungi l'attribute `#[Seed]` alla classe base di test.

```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
{
}
```

Per eseguire automaticamente solo alcuni seeder usa `#[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;
}
```

## Asserzioni disponibili

Laravel offre asserzioni dedicate al database utilizzabili sia in Pest sia in PHPUnit.

### `assertDatabaseCount`

Verifica che il numero di record nella tabella corrisponda al valore atteso.

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

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

### `assertDatabaseEmpty`

Verifica che la tabella sia vuota.

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

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

### `assertDatabaseHas`

Verifica che esistano record che corrispondono alle condizioni.

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

Verifica che non esistano record che corrispondono alle condizioni.

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

Verifica che il modello Eloquent sia soft deleted.

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

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

### `assertNotSoftDeleted`

Verifica che il modello Eloquent non sia soft deleted.

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

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

### `assertModelExists`

Verifica che il modello (o la collection di modelli) indicato esista nel DB.

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

Verifica che il modello (o la collection di modelli) non esista nel DB.

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

All'inizio del test indica il numero totale di query attese. Se il numero effettivo non corrisponde il test fallisce.

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

  // Test...
  ```

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

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


## Related topics

- [Configurazione del database](/it/database.md)
- [Test del browser (Dusk)](/it/dusk.md)
- [Migration del database](/it/migrations.md)
- [Eloquent Observers ed eventi del modello](/it/advanced/eloquent-observers.md)
- [Guida allo sviluppo di app con l'API del motore - VOICEVOX for Laravel](/it/packages/laravel-voicevox/app-guide.md)
