---
title: "Aprende Laravel: Testing con Pest"
excerpt: "Aprende a testear tu app Laravel con Pest: la diferencia entre tests de Feature y Unit, cómo crear y correr tests, tests HTTP y RefreshDatabase para tocar la base de datos."
date: "2026-07-20T10:30:00.000Z"
category: "Laravel"
author:
  name: "angel cruz"
  picture: "https://angelcruzdevcdn.nyc3.cdn.digitaloceanspaces.com/images/me/angel-cruz.png"
ogImage:
  url: "/images/open-graph/laravel-opengraph-image.png"
seo_title: "Testing en Laravel 13 con Pest: Feature, Unit y HTTP (guía)"
seo_description: "Aprende testing en Laravel 13 con Pest: tests de Feature vs Unit, crear y correr tests, tests HTTP con assertOk/assertSee y RefreshDatabase para la base de datos."
keywords:
  - laravel
  - testing
  - pest
  - php
  - laravel español
learning_path:
  series: "laravel-fundamentals"
  order: 10
  total: 13
  prev_slug: "aprende-laravel-middleware"
  next_slug: "aprende-laravel-blade-componentes"
---

Llegaste al último fundamento, y es el que hace que todo lo anterior aguante en el tiempo: **los tests verifican que tu app hace lo que debe, hoy y después de cada cambio.** Laravel viene con soporte para [Pest](https://pestphp.com) y PHPUnit de fábrica, con un `phpunit.xml` ya configurado. En esta serie usamos **Pest** por su sintaxis limpia.

## Feature vs Unit: cuál escribir

Tu carpeta `tests` trae dos directorios:

- **`tests/Unit`**: prueban una porción muy chica y aislada de tu código (normalmente un método). No arrancan la app, así que no acceden a la base de datos.
- **`tests/Feature`**: prueban una porción más grande, incluyendo una petición HTTP completa a un endpoint.

La regla oficial: **la mayoría de tus tests deberían ser de Feature.** Son los que más confianza dan de que el sistema funciona como conjunto.

## Crear un test

Con Artisan. Por defecto se crea en `tests/Feature`:

```shell
php artisan make:test UserTest
```

Para uno de Unit, agrega `--unit`:

```shell
php artisan make:test CalculadoraTest --unit
```

## Un test con Pest

La sintaxis de Pest es una función, sin clases ni boilerplate:

```php
<?php

test('la suma funciona', function () {
    expect(1 + 1)->toBe(2);
});
```

También puedes escribirlo con `it()`, que se lee más natural:

```php
it('devuelve verdadero', function () {
    expect(true)->toBeTrue();
});
```

## Tests HTTP: probar una ruta de verdad

Aquí está el valor real de los tests de Feature. Dentro del closure tienes helpers como `$this->get()` y aserciones expresivas:

```php
it('muestra la home', function () {
    $response = $this->get('/');

    $response->assertOk();          // status 200
    $response->assertSee('Bienvenido');
});
```

Aserciones que vas a usar seguido: `assertOk()`, `assertStatus(201)`, `assertSee('texto')`, `assertRedirect('/login')`.

## Tocar la base de datos: RefreshDatabase

Cuando un test crea o consulta datos, necesitas una base limpia en cada corrida. El trait `RefreshDatabase` migra una base de datos fresca por test. En Pest se activa al tope del archivo:

```php
<?php

use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('crea un post', function () {
    $this->post('/posts', [
        'title' => 'Mi primer post',
        'body' => 'Contenido de prueba',
    ]);

    $this->assertDatabaseHas('posts', [
        'title' => 'Mi primer post',
    ]);
});
```

`assertDatabaseHas()` confirma que la fila quedó guardada. Laravel usa el driver `array` para sesión y caché durante los tests, así que nada de eso ensucia tu entorno real.

## Correr los tests

Tres formas equivalentes:

```shell
php artisan test        # reporte detallado, la más cómoda
./vendor/bin/pest       # el runner de Pest directo
```

El comando `php artisan test` acepta opciones útiles como `--filter` (correr un test puntual), `--parallel` (en varios procesos) o `--coverage` (cobertura, requiere Xdebug o PCOV).

## El ciclo completo

Este es el cierre de la serie: cuando pides código a un [agente de IA en tu proyecto Laravel](/post/claude-code-proyecto-laravel), los tests son el contrato. Un cambio "terminado" que no pasa `php artisan test` no está terminado. Escribe el test, míralo fallar, escribe el código, míralo pasar.

## Siguiente Paso

Completaste los fundamentos de Laravel. El salto natural ahora es sumarle IA a tu flujo: mira [IA para desarrolladores Laravel](/post/ia-para-desarrolladores-laravel) o vuelve al índice en [Aprende Laravel desde cero](/laravel-fundamentals).

## Preguntas Frecuentes

### ¿Pest o PHPUnit para Laravel?

Los dos vienen soportados de fábrica. Pest tiene una sintaxis más limpia (funciones `test()` / `it()` en vez de clases), y es la que usamos en esta serie. Por debajo, Pest corre sobre PHPUnit.

### ¿Cuál es la diferencia entre un test de Feature y uno de Unit?

Los de Unit prueban una pieza aislada (un método) sin arrancar la app ni la base de datos. Los de Feature prueban un flujo completo, incluida una petición HTTP. La mayoría de tus tests deberían ser de Feature.

### ¿Cómo pruebo que una ruta responde bien?

Con un test de Feature: `$this->get('/ruta')` y aserciones como `assertOk()` o `assertSee('texto')`.

### ¿Para qué sirve RefreshDatabase?

Migra una base de datos limpia en cada test, así los tests que crean o consultan datos parten siempre de un estado conocido. En Pest se activa con `uses(RefreshDatabase::class)`.

### ¿Cómo corro los tests?

Con `php artisan test` (reporte detallado) o `./vendor/bin/pest`. Puedes filtrar con `--filter`, paralelizar con `--parallel` o medir cobertura con `--coverage`.

## Recursos Adicionales

- [Testing: Getting Started | Laravel 13.x](https://laravel.com/docs/13.x/testing)
- [Pest PHP](https://pestphp.com)
- [Aprende Laravel desde cero (serie completa)](/laravel-fundamentals)

---

## Sitemap

Índice completo del sitio: [/sitemap.md](https://www.angelcruz.dev/sitemap.md)

Canónico HTML: [https://www.angelcruz.dev/post/aprende-laravel-testing-pest](https://www.angelcruz.dev/post/aprende-laravel-testing-pest)
