TESTING EN LARAVEL: LA GUÍA COMPLETA PARA ESCRIBIR PRUEBAS PROFESIONALES

Laravel es uno de los frameworks de PHP más fácil de probar del mercado. Viene configurado con soporte excelente tanto para PHPUnit como para Pest, esta es la opción recomendada en nuevos proyectos desde Laravel 11+.

PHPUnit vs Pest: ¿Cuál usar?

Usar Pest en nuevos proyectos. Laravel lo instala por defecto y la comunidad lo ha adoptado masivamente
Aspecto PHPUnit Pest
Sintaxis Clásica (clases) Moderna, expresiva y legible
Velocidad de escritura Media Muy alta
Curva de aprendizaje Familiar para muchos Muy amigable
Compatibilidad 100% 100% (corre sobre PHPUnit)
Recomendación 2026 Proyectos legacy o equipos grandes Recomendado para la mayoría

Configuración inicial

Si se va a usa Pest (recomendado)

composer require pestphp/pest --dev --with-all-dependencies
composer require pestphp/pest-plugin-laravel --dev
php artisan pest:install
Laravel crea automáticamente las
  • "carpetas:tests/Feature/": Pruebas de características completas
  • "tests/Unit/": Pruebas unitarias puras

Tipos de pruebas recomendadas

  • Feature Tests (80-90% de tus pruebas): Las más valiosas
  • Unit Tests (10-15%)
  • Browser Tests (Dusk o Pest Browser): Solo lo crítico

Ejemplos prácticos

  • Feature Test básico (Pest):

    // tests/Feature/PostTest.php
    it('crea un post correctamente', function () {
        $user = User::factory()->create();
        
        $response = $this->actingAs($user)
                         ->post(route('posts.store'), [
                             'title' => 'Mi primer post',
                             'content' => 'Contenido de prueba...',
                         ]);
    
        $response->assertRedirect();
        $this->assertDatabaseHas('posts', [
            'title' => 'Mi primer post',
            'user_id' => $user->id,
        ]);
    });
    
  • Versión PHPUnit:

    public function test_crea_un_post_correctamente()
    {
        $user = User::factory()->create();
        
        $response = $this->actingAs($user)
                         ->post(route('posts.store'), [
                             'title' => 'Mi primer post',
                             'content' => 'Contenido de prueba...',
                         ]);
    
        $response->assertRedirect();
        $this->assertDatabaseHas('posts', [
            'title' => 'Mi primer post',
            'user_id' => $user->id,
        ]);
    }
    
  • Pruebas en base de datos:

    use Illuminate\Foundation\Testing\RefreshDatabase;
    
    uses(RefreshDatabase::class);   // En Pest
    
    // O en PHPUnit
    class PostTest extends TestCase
    {
        use RefreshDatabase;
    }
    
    Otras traits útiles:
    • "DatabaseTransactions"
    • "DatabaseMigrations" (más lento)
    • "WithoutMiddleware"

Crear datos de prueba con "factories" y "seeders"

// Crear datos con factories
$user = User::factory()->create();
$users = User::factory(10)->create();

$post = Post::factory()->for($user)->create([
    'published_at' => now(),
]);

Mocking y Faking

Faking es una funcionalidad de Laravel que permite simular el comportamiento de ciertos servicios durante los tests, sin que realmente se ejecuten.
Mail::fake();
Mail::assertSent(OrderShipped::class, 1);

Queue::fake();
Queue::assertPushed(SendEmailJob::class);

Event::fake();
Event::assertDispatched(UserRegistered::class);

Storage::fake('public');

Autenticación y Authorization

$this->actingAs($user);                    // Login normal
$this->actingAs($user, 'api');             // Guard específico
$this->assertAuthenticatedAs($user);
$this->withoutExceptionHandling();         // Ver errores detallados en tests

Pruebas del navegador

La opción moderna y recomendada es Pest Browser Testing a partir de la versión 4 de Pest y la opción más clásica es Laravel Dusk
//Instalación de Laravel Dusk
composer require laravel/dusk --dev
php artisan dusk:install
Ejemplo con Laravel Dusk:

it('puede iniciar sesión', function () {
    $user = User::factory()->create(['email' => 'test@example.com']);

    $browser->visit('/login')
            ->type('email', 'test@example.com')
            ->type('password', 'password')
            ->press('Iniciar sesión')
            ->assertPathIs('/dashboard');
});

Mejores Prácticas

  • Priorizar Feature Tests sobre Unit Tests.
  • Usar Form Requests para validar y probarlos por separado.
  • Mantener los tests rápidos evitando sleeps innecesarios.
  • Usar parallel testing:

    php artisan test --parallel
    
  • Implementar CI/CD con tests (GitHub Actions, Forge, etc.).
  • Apuntar a cobertura > 80% en código crítico.
  • Usar Arch Testing con Pest para hacer cumplir la arquitectura.
  • Evitar probar implementación interna, y probar comportamiento.

Comandos útiles

php artisan test                    # Ejecuta todo
php artisan test --filter=Post      # Filtrar por nombre
php artisan test --parallel         # En paralelo
php artisan test --coverage         # Cobertura
php artisan pest:watch              # Watch mode (Pest)