¿Dónde colocamos cada una de nuestras clases de prueba?
Para responder a la primera pregunta debemos poder diferenciar
¿qué tipo de pruebas contiene cada una de nuestras clases?
y saber ¿cómo va a ejecutar Laravel las pruebas?
Primero lo fácil, Laravel ejecuta las pruebas en este orden:
primero las pruebas dentro del directorio "Unit",
seguidamente las pruebas dentro del directorio "Feature".
Esto es por dos motivos, se espera que las primeras sean rápidas
y las segundas, no tanto. Además, partes que conforman las
"pruebas de características" deberán pasar previamente
"pruebas unitarias".
Dentro de cada uno de los directorios principales,
la ejecución sigue un orden alfabético con las clases de prueba,
y dentro de éstas, se ejecutan las pruebas de arriba a abajo.
Dicho esto, en general en Feature pondremos
pruebas sobre "características completas del sistema", lo que incluye
una petición Http, que implica una ruta, un controlador,
probablemente llamadas a la BD, middlewares, etc.
Incluyen bastante pasos y cierta complejidad...
Por eso dije que dependen a su vez de partes más pequeñas
que deben pasar previamente, al menos en parte, pruebas unitarias.
La prueba unitaria se usa con funcionalidades concretas,
entonces en Unit se pondrán las clases para
probar las funciones / métodos que tenemos dentro de Helpers,
Services, FormRequest, etc.
Dentro de Feature y Unit
deberemos crear una estructura de carpetas que refleje la de la aplicación,
por ejemplo, Si tenemos una clase "Dates" en el directorio "app/Helpers",
crearíamos la clase de prueba con:
php artisan make:test app/Helpers/DatesTest --unit
¿Qué debemos probar y cómo?
En este caso voy a tratar de responder a las preguntas
¿Qué debemos probar? y
¿Cómo debemos probarlo?,
difíciles de separar y también de responder.
Existen pruebas muy genéricas, por ejemplo,
queremos saber si hay usuarios en la base de datos y sí,
existe registrado un email determinado.
Para ello usaríamos dos aserciones consecutivas,
yendo de una más general a otra más específica.
Cuidado, si somos puristas, hay cosas que no deberían hacerse
con pruebas unitarias, éstas no deberían acceder a la BD
(deben de ser "independientes" y rápidas).
Comprobar la existencia de usuarios o un email, es necesario
para el funcionamiento del sistema debido a los requisitos
de la aplicación o sus características, ¿pueden englobarse
dentro de las pruebas de características?, si y no, ya que
no cubren características completas...
En realidad, vamos a probar una fracción de una prueba de características.
Voy a poner mi ejemplo dentro de Unit,
aunque no sea "estrictamente" pruebas unitarias.
Primero creo la clase:
php artisan make:test app/Models/UserTest --unit
Obtengo esto:
<?php
namespace Tests\Unit\app\Models;
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase
{
/**
* A basic unit test example.
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
Voy a cambiar la sentencia
use
inicial y escribiré 2 aserciones, cada una en una prueba.
Además, uso setUp()
para obtener al inicio todos los usuarios registrados.
<?php
namespace Tests\Unit\app\Models;
use Tests\TestCase;
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
$this->users = User::all();
}
public function test_has_users()
{
$result = ($this->users->count() > 0);
$this->assertTrue($result);
}
public function test_some_user_has_the_email()
{
$email = 'foo@ironwoods.es';
$userEmails = $this->users
->pluck('email')
->toArray();
$this->assertContains($email, $userEmails);
}
}
Pasar estas pruebas es un paso previo a probar un
sistema de autenticación u otros que requieran usuarios / emails,
como una lista de subscriptores ¿ves que acabo de mencionar
dos features.
Lo tendremos en cuenta al ordenar nuestras pruebas.
Habitualmente, iremos de una prueba general a otras más específicas,
por lo que se requiere cierto orden en la disposición de las aserciones
dentro de la clase.
En mi ejemplo si se han borrado todos los usuarios,
no hace falta llegar a la segunda aserción, podría borrarse
el usuario con el email a verificar, o cambiar este,
esto no hace fallar la primera aserción.
Si hemos identificado una prueba unitaria y el método
a probar no es lo suficientemente sencillo,
es decir requieren varias pruebas unitarias,
requiere una refactorización.