Cómo crear pruebas unitarias en Laravel: Una guía práctica con ejemplos reales



¿Estás listo para mejorar tu habilidad en pruebas unitarias? ¿Estás interesado en descubrir cómo crear pruebas unitarias efectivas con Laravel? Si es así, entonces has venido al lugar correcto. En esta publicación te muestro una guía práctica para implementar pruebas unitarias con Laravel para que puedas comprender mejor cómo funciona esta herramienta.

¿Qué son las pruebas unitarias?

En Laravel puedes crear dos tipos de pruebas Feature test y Unit test. Unit test son pruebas para componentes individuales, por ejemplo puedes probar si tu aplicación puede ejecutar tareas como guardar información en la base de datos, realizar algún cálculo, etc.

Los Feature test son pruebas más amplias, por ejemplo puedes probar páginas completas de tu aplicación y comprobar que interactúen bien con servicios externos, bases de datos, etc.

Por ejemplo, si una URL de tu aplicación debe cargar datos de una API rest y mostrarlos, puedes pedirle que cargue la URL y revisar el contenido que genera en busca de ciertas palabras clave.

Este artículo se centra en los Unit test, o pruebas unitarias.

Configuración de pruebas unitarias en Laravel

Afortunadamente, Laravel ya viene configurado para ejecutar pruebas unitarias, lo único que debes de hacer es una copia de tu archivo .env y colocarle el nombre .env.testing en este archivo debes de colocar los datos para acceder a una base de datos para pruebas, ya que las pruebas usualmente deben de escribir y borrar datos.

También debes de crear la base de datos de pruebas y configurar un usuario.

¿Cómo ejecutar pruebas unitarias en Laravel?

Para ejecutar las pruebas unitarias debes de abrir una ventana de consola y navegar hasta el directorio de tu aplicación. Luego solo ejecutas este comando para que se corran todas las pruebas unitarias.

php artisan test

Al finalizar las pruebas verás un resultado como este, indicando los resultados.

Resultados de pruebas unitarias en laravel

Ejemplos reales de pruebas unitarias en Laravel

Vamos a analizar las pruebas unitarias de la aplicación rocketlog, esta aplicación fue creada por Jess Archer, ella es una programadora full stack y ha contribuido en el desarrollo de Laravel, por lo que la convierte en una excelente opción para aprender sobre pruebas unitarias en Laravel.

Primero debemos entender un poco que es lo que hace esta aplicación, para saber que es lo que está incluyendo en las pruebas unitarias.

Rocketlog es aplicación de tareas del tipo ToDo list, pero con un giro: Está basada en el método bullet journal creado por Ryder Carroll.

Vamos a revisar la parte en que se hacen las pruebas unitarias referentes a las tareas (llamadas bullets en esta aplicación), puedes ver el código completo de las pruebas unitarias en este enlace.

Lo primero que hay que notar, es que incluye los modelos de las tablas de bases de datos que se usarán en las pruebas y además incluye algunas librerías que facilitaran las pruebas.

Aquí definen los modelos y utilidades que se usaran en las pruebas unitarias en Laravel.

Usando RefreshDatabase se podrá obtener una base de datos limpia al inicio de cada prueba, de esta forma no quedarán todos los registros que se insertaron o modificaron en las pruebas anteriores. Con WithFaker se pueden generar textos aleatorios como nombres, emails, números o textos del tamaño que necesitas.

Probar que se necesita autenticación para ver las tareas.

Ahora vamos a lo que más nos interesan que son las pruebas unitarias, la primera prueba que hace es verificar que las bullets (tareas) solo se puedan ver si has iniciado sesión. Eso lo hace con este código:

 public function test_it_requires_authentication()
 {
    $this
        ->get('/daily-log')
        ->assertRedirect('/login');
}

Como puedes ver lo que hace es intentar cargar la url /daily-log y con el método assertRedirect se indica que la prueba es un éxito si te redirige a la página de login, de otra forma la prueba fallará.

Probar que no se puedan ver las tareas de otros

Ahora se necesita una prueba que verifique que un usuario no puede ver las tareas de otros usuarios, para eso se creó esta prueba unitaria:

public function test_it_only_shows_my_bullets()
{
	/** @var \App\Models\User */
	$user = User::factory()->create();
	$myBullet = $user->bullets()->save(
		Bullet::factory()->make(['date' => now()->format('Y-m-d')])
	);
	$otherBullet = Bullet::factory()->create(['date' => now()->format('Y-m-d')]);

	$response = $this
		->actingAs($user)
		->get('/daily-log');

	$response->assertOk();
	$response->assertSee($myBullet->name);
	$response->assertDontSee($otherBullet->name);
}

Esta prueba es más complicada, primero crea un nuevo usuario y le agrega una bullet (tarea), luego crea otra bullet, pero sin estar asociada a un usuario. Después consulta la url /daily-log que se muestra al usuario que se creó al inicio (usando el método actingAs($user)).

Ahora se necesita verificar los resultados, y se usan estos métodos de las pruebas unitarias:

  • assertOk: Para verificar que la página se cargó con éxito (/daily-log)
  • assertSee: Se usa para verificar que en la página que se cargó este la tarea que se creó, esto se hace buscando en el texto de la página web, el nombre de la tarea.
  • assertDontSee: Se usa para verificar que en la página que se cargó NO se vea la tarea creada sin usuario.

Probar si se guardan las tareas que se crean.

Ahora se necesita que se pruebe si las tareas que se crean se almacenen en la base de datos, para eso se utiliza esta prueba:

public function test_it_stores_bullets()
{
	Event::fake();
	/** @var \App\Models\User */
	$user = User::factory()->create();

	$response = $this
		->actingAs($user)
		->post('/daily-log', [
			'date' => now()->format('Y-m-d'),
			'name' => $name = $this->faker->text(),
		]);

	$response->assertRedirect('/daily-log');
	$this->assertDatabaseHas('bullets', [
		'user_id' => $user->id,
		'date' => now()->format('Y-m-d'),
		'name' => $name,
		'type' => 'task',
		'state' => 'incomplete',
	]);
	Event::assertDispatched(fn (DailyLogUpdated $event) => $event->userId === $user->id);
}

En este código, primero crea un usuario y luego le envía los parámetros de la tarea a crear, para esto se usa el método post, que es con el que se almacenan la tarea en la base de datos.

Luego prueba si se redirige la ruta /daily-log con el método assertRedirect y con el método assertDatabaseHas se revisa si el registro creado se encuentra en la tabla bullets.

Otras pruebas unitarias

Después se hacen otras pruebas, pero el código es básicamente el mismo. Puedes probar muchas secciones de tu aplicación, cargando y enviando datos a las URL que necesitas probar y luego verificar si se despliega algún texto, si se redirecciona a otro lugar o si puedes ver algún cambio esperado en la base de datos.

Conclusiones

Las pruebas unitarias pueden consumir tiempo de los programadores, pero son una gran ayuda para encontrar errores y probar el sistema.

Si nunca has utilizado las pruebas unitarias, te recomiendo que lo intentes podrían ayudarte a crear código mejor probado y con menos errores.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *