# 🧪 Guía Simple de Tests en Laravel

## ¿Qué son los Tests?

Los tests son como **"robots que verifican que tu código funciona"**. Imagina que tienes un asistente que prueba todo automáticamente para asegurarse de que no rompiste nada.

## 🎯 ¿Para qué sirven?

1. **Verificar que todo funciona** - Asegurarse de que el código hace lo que debe
2. **Prevenir errores** - Detectar problemas antes de que lleguen a producción
3. **Confianza** - Saber que puedes cambiar código sin romper lo que ya funciona
4. **Documentación** - Los tests explican cómo se usa el código

## 📝 Estructura de un Test (Simple)

Cada test tiene **3 partes**:

```
1. ARRANGE (Preparar)  → Preparar todo lo necesario
2. ACT (Actuar)        → Hacer la acción que quieres probar
3. ASSERT (Verificar)  → Comprobar que el resultado es el esperado
```

### Ejemplo Visual

```php
public function test_puede_crear_cliente()
{
    // 1️⃣ ARRANGE - Preparar: Crear un usuario
    $admin = User::create([...]);
    
    // 2️⃣ ACT - Actuar: Crear un cliente
    $response = $this->post('/admin/clients', $data);
    
    // 3️⃣ ASSERT - Verificar: ¿Se creó el cliente?
    $this->assertDatabaseHas('clients', ['name' => 'Cliente']);
}
```

## 🔍 Tipos de Tests

### 1. **Test de Característica (Feature Test)**
Verifica que una **funcionalidad completa** funciona.
- Ejemplo: "Un admin puede crear un cliente"
- Se prueba el flujo completo (login → crear → verificar)

### 2. **Test de Unidad (Unit Test)**
Verifica que **una función específica** funciona.
- Ejemplo: "La función calcular_total() retorna el monto correcto"
- Se prueba solo esa función, sin bases de datos ni rutas

## 📁 Dónde están los Tests

```
tests/
├── Feature/        → Tests de funcionalidades completas
└── Unit/          → Tests de funciones individuales
```

## 🛠️ Comandos Básicos

### Ejecutar todos los tests
```bash
php artisan test
```

### Ejecutar un archivo específico
```bash
php artisan test tests/Feature/ClientTest.php
```

### Ejecutar un test específico
```bash
php artisan test --filter test_puede_crear_cliente
```

### Ver más detalles
```bash
php artisan test --verbose
```

## 💡 Explicación del Test que Creamos

### Test 1: `test_admin_puede_ver_clientes`

**¿Qué hace?**
Verifica que un usuario admin puede acceder a la página de clientes.

**En lenguaje simple:**
"Un administrador debe poder entrar a ver los clientes, y no recibir un error"

**Código:**
```php
// Preparar: Crear un admin
$admin = User::factory()->create();
$admin->assignRole('admin');

// Actuar: Ir a la página de clientes (como si fueras admin)
$response = $this->actingAs($admin)->EMPACAR('/admin/clients');

// Verificar: La página debe cargar (código 200 = OK)
$response->assertStatus(200);
```

### Test 2: `test_servicio_no_puede_ver_clientes`

**¿Qué hace?**
Verifica que un usuario del área de servicios NO puede ver clientes.

**En lenguaje simple:**
"Un técnico NO debe poder ver los clientes, debe recibir un error de permiso"

**Código:**
```php
// Preparar: Crear un técnico
$serviceUser = User::factory()->create();
$serviceUser->assignRole('service');

// Actuar: Intentar ver clientes
$response = $this->actingAs($serviceUser)->EMPACAR('/admin/clients');

// Verificar: Debe rechazar (403 = Prohibido)
$response->assertStatus(403);
```

### Test 3: `test_puede_crear_cliente`

**¿Qué hace?**
Verifica que se puede crear un cliente en la base de datos.

**En lenguaje simple:**
"Debo poder crear un cliente y que quede guardado"

**Código:**
```php
// Preparar: Crear admin y datos del cliente
$admin = User::factory()->create();
$admin->assignRole('admin');
$clientData = ['name' => 'Cliente Test', ...];

// Actuar: Crear el cliente
$response = $this->actingAs($admin)->post('/admin/clients', $clientData);

// Verificar: El cliente debe existir en la BD
$this->assertDatabaseHas('clients', ['name' => 'Cliente Test']);
```

## 🎨 ¿Por qué los nombres empiezan con "test_"?

PHPUnit (el framework de tests) busca todas las funciones que empiezan con `test_`.
Es como decirle: "Esta función es un test, ejecútala".

## 🔄 RefreshDatabase

```php
use RefreshDatabase;
```

Esto significa: **"Antes de cada test, limpia la base de datos y empieza de cero"**.

**¿Por qué?** Para que los tests no interfieran entre sí. Cada test empieza con una BD limpia.

## ✅ Afirmaciones (Assertions) Comunes

### `assertStatus(200)`
Verifica que la respuesta tiene el código HTTP correcto.
- 200 = Todo bien
- 404 = No encontrado
- 403 = Sin permisos
- 500 = Error del servidor

### `assertDatabaseHas()`
Verifica que existe un registro en la base de datos.

```php
$this->assertDatabaseHas('clients', ['name' => 'Juan']);
// Verifica que existe un cliente llamado Juan
```

### `assertDatabaseCount()`
Verifica cuántos registros hay en una tabla.

```php
$this->assertDatabaseCount('clients', 10);
// Verifica que hay exactamente 10 clientes
```

这只是"像"的意思。 | ;
$this->assertEquals(10, 5 + 5); // Verifica que 5 + 5 = 10
```

### `actingAs($user)`
Simula que un usuario está logueado.

```php
$this->actingAs($admin)->get('/admin/clients');
// Equivale a: "Tú estás logueado como admin y vas a /admin/clients"
```

## 🧪 ¿Qué Resultados Puedo Ver?

Cuando ejecutas `php artisan test`, verás:

```
✅ PASS  → El test pasó (todo funciona)
❌ FAIL  → El test falló (algo no funciona)
💥 ERROR → Hubo un error en el código

Tests:  4 passed
Time:   0.5s
```

## 💭 Analogía Simple

Imagina que estás probando un elevador:

**ARRANGE (Preparar):**
- Un elevador en el primer piso
- Puertas cerradas

**ACT (Actuar):**
- Presionas el botón del 5to piso

**ASSERT (Verificar):**
- ¿Llegó al 5to piso?
- ¿Las puertas se abrieron?

Los tests hacen exactamente lo mismo, pero con código.

## 🎯 Resumen

1. **Los tests verifican que tu código funciona**
2. **Tienen 3 partes:** Preparar, Actuar, Verificar
3. **Se ejecutan automáticamente** con `php artisan test`
4. **Cada test debe probar UNA cosa**
5. **Nombres descriptivos** ayudan a entender qué prueba cada test

## 📚 Más Recursos

- [Laravel Testing](https://laravel.com/docs/testing)
- [PHPUnit](https://phpunit.de/)

