Pruebas HTTP en PHP con Artisan y Base de Datos

Clase 16 de 24Curso Básico de Testing con PHP y Laravel

Contenido del curso

Conceptos

Proyecto

Resumen

Probar que una ruta responde correctamente y muestra el contenido esperado es el primer paso para construir aplicaciones confiables con Laravel. En esta práctica se crea un test HTTP desde cero, se configura el modelo, la vista y la base de datos en memoria para que todo funcione en armonía con el ciclo red-green del desarrollo guiado por pruebas.

¿Cómo se crea un test HTTP en Laravel?

El punto de partida es generar el archivo de prueba con el comando php artisan make:test HomeTest [0:42]. Este archivo se ubica dentro de la carpeta tests/Feature, que es donde Laravel agrupa las pruebas orientadas a funcionalidades completas, incluyendo peticiones HTTP.

Una vez creado, se eliminan los ejemplos que vienen por defecto para trabajar únicamente con el archivo HomeTest y evitar distracciones [1:06].

La primera prueba busca verificar qué sucede cuando no existen datos en la aplicación:

php public function test_home_empty(): void { $this->get('/') ->assertStatus(200) ->assertSeeText('No hay etiquetas'); }

  • Se realiza una petición GET a la ruta principal / [1:30].
  • Se comprueba que el código de estado sea 200, lo que confirma que la conexión es exitosa [1:42].
  • Se verifica que el texto "No hay etiquetas" aparezca en pantalla [1:50].

Al ejecutar php artisan test, la prueba falla porque la vista todavía no contiene ese texto ni la lógica necesaria [2:05]. Este fallo es esperado y forma parte del flujo normal de TDD.

¿Qué elementos del proyecto hay que preparar?

Como el proyecto trabajará con etiquetas almacenadas en base de datos, es necesario crear el modelo junto con su migración y factory en un solo comando [2:30]:

bash php artisan make:model Tag -mf

Este comando genera tres archivos de golpe: el modelo Tag, su archivo de migración y su factory, que serán útiles más adelante para poblar datos de prueba.

¿Cómo se configura la ruta y la vista?

En el archivo de rutas se modifica la ruta principal para que envíe las etiquetas a la vista welcome [2:55]:

php Route::get('/', function () { return view('welcome', [ 'tags' => Tag::get(), ]); });

Dentro de la vista welcome.blade.php se simplifica el HTML, dejando solo un título y una tabla. La directiva @forelse de Blade resulta clave aquí [3:40]:

html

<h1>Listado de etiquetas</h1> <table> @forelse($tags as $tag) {{-- contenido cuando hay datos --}} @empty <tr> <td><p>No hay etiquetas</p></td> </tr> @endforelse </table>

La directiva @forelse funciona como un foreach con una condicional integrada: si la colección está vacía, ejecuta el bloque @empty y muestra el mensaje "No hay etiquetas" [3:55]. Esto es exactamente lo que la prueba espera encontrar.

¿Por qué es necesario configurar la base de datos en memoria?

Al ejecutar el test, Laravel intenta hacer la consulta Tag::get(), lo que requiere que la tabla exista. Sin una base de datos configurada para pruebas, el test falla con un error de conexión [5:05].

Para resolverlo se necesitan dos acciones:

  • Agregar el trait RefreshDatabase en la clase de prueba, lo que indica que las migraciones deben ejecutarse antes de cada test [5:25].
  • Descomentar las dos líneas en el archivo phpunit.xml que configuran SQLite en memoria [5:35].

xml <env name="DB_CONNECTION" value="sqlite"/> <env name="DB_DATABASE" value=":memory:"/>

Con esta configuración, cada vez que se ejecuten las pruebas se crea una base de datos temporal, se corren las migraciones y luego se destruye todo. La tabla tags existe pero está vacía, por lo que @forelse cae en el bloque @empty y el texto "No hay etiquetas" aparece correctamente [5:50].

¿Cuál es el ciclo completo de esta prueba?

El flujo se resume así:

  • La prueba hace un GET a / y espera status 200.
  • La ruta consulta Tag::get() y pasa la colección a la vista.
  • Como la tabla existe pero no tiene registros, @forelse muestra el mensaje del bloque @empty.
  • La aserción assertSeeText encuentra el texto y la prueba pasa en verde [6:00].

Comprender este ciclo evita confusiones frecuentes: la consulta necesita que la tabla exista aunque esté vacía, y eso solo ocurre cuando la base de datos de pruebas y las migraciones están correctamente configuradas.

¿Has tenido errores inesperados al configurar tus primeros tests HTTP? Comparte tu experiencia en los comentarios.