f in x
Laravel Testing con Pest — Feature Test e Unit Test per Codice che Non si Rompe
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Sviluppo di siti web

Laravel Testing con Pest — Feature Test e Unit Test per Codice che Non si Rompe

[2026-07-12] Author: Ing. Calogero Bono
Zenithby Meteora Web Il sistema operativo della tua attività. Social, clienti, prenotazioni e fatture in un'unica piattaforma. Palestre, barber, professionisti. Scopri Zenith Demo gratis · senza carta

Hai mai lanciato una suite di test Laravel e aspettato più di 10 secondi per un risultato? O peggio: hai visto un test fallire senza capire perché, e hai passato un'ora a inseguire un mock sbagliato? Succede a tutti. Il problema è che molti sviluppatori trattano i test come un obbligo noioso, non come uno strumento per scrivere codice migliore più velocemente.

Noi, di Meteora Web, lavoriamo con Laravel su progetti reali da anni: piattaforme proprietarie, e-commerce custom, API per clienti. E abbiamo sperimentato il cambiamento radicale che porta Pest PHP. Non è solo una sintassi più carina: è un cambio di paradigma nella leggibilità e nella velocità di scrittura dei test. In questa guida ti mostriamo come passare da test PHPUnit pesanti a test Pest snelli, e soprattutto come distinguere quando usare un unit test e quando un feature test per non sprecare tempo.

Perché Pest PHP è meglio del classico PHPUnit per i test Laravel?

PHPUnit è lo standard de facto, ma la sua sintassi con classi e metodi ereditati da TestCase rende i test verbosi. Ogni test richiede una classe, un metodo, e spesso un lungo setup. Pest riscrive l'esperienza: ti dà funzioni annidate, descrizioni in linguaggio naturale, e una chiarezza che fa la differenza quando torni sul codice dopo mesi.

Sponsored Protocol

Esempio concreto: lo stesso test in PHPUnit e Pest.

// PHPUnit class
class UserTest extends TestCase
{
    public function test_it_creates_a_user()
    {
        $user = User::factory()->create();
        $this->assertDatabaseHas('users', ['email' => $user->email]);
    }
}

// Pest
test('creates a user', function () {
    $user = User::factory()->create();
    $this->assertDatabaseHas('users', ['email' => $user->email]);
});

Pest è più compatto, non richiede classi, e supporta le higher order tests per catenare asserzioni in modo fluido. Inoltre, le funzioni beforeEach() e afterEach() sostituiscono i metodi setUp() e tearDown() con una sintassi dichiarativa.

Come distinguere un Unit Test da un Feature Test in Laravel?

Questa è la domanda che fa più danni. Sbagliare livello di test significa o scrivere test fragili (che si rompono al primo refactoring) o test troppo lenti (che chiamano il database quando non serve).

Unit test: isolati e veloci

Un unit test verifica una singola classe o metodo, senza toccare il database, le route o altre dipendenze esterne. Usa mock o stub per isolare il soggetto. Quando usarlo: per servizi, helper, calcoli, logica di business pura. In Laravel, un esempio è testare un SubscriptionService che calcola la scadenza di un abbonamento.

Sponsored Protocol

// Pest - unit test con mock
test('subscription is active when end date is in future', function () {
    $service = new SubscriptionService();
    $user = Mockery::mock(User::class);
    $user->shouldReceive('subscriptionEndAt')
         ->once()
         ->andReturn(now()->addDays(10));
    expect($service->isActive($user))->toBeTrue();
});

Velocità: questi test girano in millisecondi, nessuna connessione al database. Li lanci centinaia di volte durante lo sviluppo.

Feature test: integrazione end-to-end (ma leggera)

Un feature test in Laravel verifica un flusso completo: una richiesta HTTP, la logica del controller, l'interazione con il database, la risposta. Non usa mock per Eloquent o il database; usa la transazione del database (tramite RefreshDatabase o DatabaseTransactions). Devono essere più lenti, ma coprono la catena di valore.

// Pest - feature test per API
test('guests can register', function () {
    $response = $this->postJson('/api/register', [
        'name' => 'Mario Rossi',
        'email' => 'mario@example.com',
        'password' => 'Password123!',
        'password_confirmation' => 'Password123!',
    ]);

    $response->assertStatus(201)
             ->assertJsonStructure(['data' => ['token', 'user']]);

    $this->assertDatabaseHas('users', ['email' => 'mario@example.com']);
});

Regola pratica: se il test tocca il database o le route, è feature test. Se isola una singola classe, è unit test. Non mescolare mai i due nella stessa suite per non confondere i tempi di esecuzione.

Sponsored Protocol

Come strutturare i test con Pest in un progetto Laravel?

Pest si installa con composer require pestphp/pest --dev e si configura con un file tests/Pest.php. Noi di Meteora Web usiamo questa struttura:

tests/
├── Feature/
│   ├── Auth/
│   │   ├── LoginTest.php
│   │   └── RegisterTest.php
│   └── Api/
│       └── ProductsTest.php
├── Unit/
│   ├── Services/
│   │   └── SubscriptionServiceTest.php
│   └── Helpers/
│       └── PriceFormatterTest.php
├── Pest.php
└── TestCase.php

Ogni file Test.php contiene più test con la sintassi test() o describe() che raggruppa i test correlati. Usa describe per organizzare i contesti:

describe('SubscriptionService', function () {
    test('returns true for active subscriptions', function () { ... });
    test('returns false for expired subscriptions', function () { ... });
});

Pest genera automaticamente un'etichetta descrittiva nei report, rendendo i test molto più leggibili.

Sponsored Protocol

Quali best practice seguire per test veloci e affidabili?

Abbiamo visto troppi progetti con test che impiegano 3 minuti per girare. Ecco le nostre regole:

  • Usa RefreshDatabase con criterio: per feature test, usa RefreshDatabase solo quando necessario; spesso DatabaseTransactions è più veloce perché non esegue le migration a ogni test.
  • Non mockare ciò che non possiedi: Evita di mockare classi di librerie esterne a meno che non siano realmente lente. Usa i loro veri metodi quando possibile.
  • Factories con stati: Definisci stati specifici nelle factory (es. User::factory()->unverified()->create()) per creare dati precisi senza codice duplicato nei test.
  • Testa solo ciò che deve funzionare: Non coprire ogni setter con un test. Concentrati sui comportamenti critici: validazione, calcoli, autorizzazione, edge case.
  • Usa il trait WithFaker con moderazione: Preferisci dati deterministici per evitare test flaky.

Come eseguire i test in CI e integrarli con il flusso di lavoro?

Noi eseguiamo i test su ogni push con GitHub Actions. Pest si integra perfettamente con php artisan test (usa Pest di default se installato). Un esempio di workflow minimo:

Sponsored Protocol

name: Laravel Tests
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - run: composer install --no-interaction
      - run: cp .env.example .env
      - run: php artisan key:generate
      - run: php artisan migrate --force
      - run: php artisan test

Con Pest, i report di errore sono chiari e includono il contesto describe, facilitando il debugging.

Cosa fare adesso

  1. Installa Pest nel tuo progetto Laravel: composer require pestphp/pest --dev e segui la guida ufficiale per la migrazione.
  2. Converti un bugfix esistente in test: prima di correggere un errore, scrivi un test che lo riproduce. Poi correggi. È il ciclo TDD più pragmatico.
  3. Separa unit test da feature test: sposta i test che non toccano il database in tests/Unit e quelli di integrazione in tests/Feature.
  4. Definisci tre stati per ogni factory: default, unverified, admin. Ti coprono l'80% dei casi.
  5. Leggi la documentazione ufficiale di Pest per approfondire le higher order tests e le architetture di test avanzate.

Se vuoi capire come inserire i test in un'architettura Laravel enterprise completa, visita la nostra pagina pillar su Laravel.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // WEB AGENCY

Costruiamo la presenza digitale che la tua azienda merita.

Siti web, social, pubblicità online, e-commerce e hosting performante: ingegnerizzati con metodo da ingegneri informatici a Sciacca, per tutta Italia.

> MW_JOURNAL

> READ_ALL()