Introducción

Laravel proporciona una API muy fluida para hacer solicitudes HTTP a tu aplicación y examinar la salida. Por ejemplo, demos un vistazo a la prueba funcional definida a continuación:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
    * A basic test example.
    *
    * @return void
    */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

El método get simula una solicitud GET dentro de la aplicación, mientras que el método assertStatus comprueba que la respuesta devuelta debería tener el código de estado HTTP dado. Además de esta sencilla aserción, Laravel también contiene una variedad de aserciones para inspeccionar de la respuesta los encabezados, contenidos, estructura JSON y más.

Personalizando encabezados de solicitud

Puedes usar el método withHeaders para personalizar los encabezados de la solicitud antes que sean enviados a la aplicación. Esto permitirá que agregues algunos encabezados personalizados de tu preferencia a la solicitud:

<?php

class ExampleTest extends TestCase
{
    /**
    * A basic functional test example.
    *
    * @return void
    */
    public function testBasicExample()
    {
        $response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}

El middleware CSRF es automáticamente deshabilitado cuando se ejecutan las pruebas.

Cookies

Puedes usar los métodos withCookie o withCookies para establecer los valores de cookie antes de hacer una solicitud. El método withCookie acepta un nombre y valor de cookie como sus dos argumentos, mientras que el método withCookies acepta un arreglo de pares de nombre / valor:

<?php

class ExampleTest extends TestCase
{
    public function testCookies()
    {
        $response = $this->withCookie('color', 'blue')->get('/');

        $response = $this->withCookies([
            'color' => 'blue',
            'name' => 'Taylor',
        ])->get('/');
    }
}

Depurando respuestas

Luego de hacer una solicitud de prueba a tu aplicación, los métodos dump, dumpHeaders y dumpSession pueden ser usados para examinar y depurar el contenido de la respuesta:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->dumpHeaders();

        $response->dumpSession();

        $response->dump();
    }
}

Sesión y autenticación

Laravel proporciona varias funciones helper para trabajar con la sesión durante las pruebas HTTP. Primero, puedes colocar los datos de la sesión en un arreglo dado usando el método withSession. Esto es útil para cargar la sesión con los datos antes de realizar una solicitud a tu aplicación:

<?php

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $response = $this->withSession(['foo' => 'bar'])
                         ->get('/');
    }
}

Un uso común de la sesión es para mantener el estado del usuario autenticado. El método helper actingAs proporciona una forma sencilla de autenticar un usuario dado como el usuario actual. Por ejemplo, podemos usar un model factory para generar y autenticar un usuario:

<?php

use App\User;

class ExampleTest extends TestCase
{
    public function testApplication()
    {
        $user = factory(User::class)->create();

        $response = $this->actingAs($user)
                         ->withSession(['foo' => 'bar'])
                         ->get('/');
    }
}

También puedes especificar qué «guard» debe ser usado para autenticar el usuario dado al pasar el nombre del guard como segundo argumento del método actingAs:

$this->actingAs($user, 'api')

Probando APIs JSON

Laravel también proporciona varios helpers para probar APIs JSON y sus respuestas. Por ejemplo, los métodos json, getJson, postJson, putJson, patchJson, deleteJson y optionsJson pueden ser usados para hacer solicitudes JSON con varios verbos HTTP. También puedes pasar datos y encabezados fácilmente a estos métodos. Para empezar, vamos a escribir una prueba para hacer una solicitud POST a /user y comprobar que los datos esperados fueron devueltos:

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->postJson('/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}

El método assertJson convierte la respuesta a un arreglo y utiliza PHPUnit::assertArraySubset para verificar que el arreglo dado exista dentro de la respuesta JSON devuelta por la aplicación. Así, si hay otras propiedades en la respuesta JSON, esta prueba aún pasará siempre y cuando el fragmento dado esté presente.

Verificando una coincidencia JSON exacta

Si prefieres verificar que el arreglo dado esté contenido exactamente en la respuesta JSON devuelta por la aplicación, deberías usar el método assertExactJson:

<?php

class ExampleTest extends TestCase
{
    /**
    * A basic functional test example.
    *
    * @return void
    */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertExactJson([
                'created' => true,
            ]);
    }
}

Verificando rutas de JSON

Si quieres verificar que la respuesta JSON contenga algunos datos dados en una ruta específica, deberías usar el método assertJsonPath:

<?php

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJsonPath('team.owner.name', 'foo')
    }
}

Probando subidas de archivos

La clase Illuminate\Http\UploadedFile proporciona un método fake el cual puede ser usado para generar archivos de prueba o imágenes para prueba. Esto, combinado con el método fake de la clase facade Storage simplifica grandemente la prueba de subidas de archivos. Por ejemplo, puedes combinar estas dos características para probar fácilmente un formulario de subida de un avatar:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function testAvatarUpload()
    {
        Storage::fake('avatars');

        $file = UploadedFile::fake()->image('avatar.jpg');

        $response = $this->json('POST', '/avatar', [
            'avatar' => $file,
        ]);

        // Assert the file was stored...
        Storage::disk('avatars')->assertExists($file->hashName());

        // Assert a file does not exist...
        Storage::disk('avatars')->assertMissing('missing.jpg');
    }
}

Personalización de archivo fake

Al momento de crear archivos usando el método fake, puedes especificar el ancho, la altura y el tamaño de la imagen con el propósito de probar mejor tus reglas de validación:

UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

Además de crear imágenes, puedes crear archivos de cualquier otro tipo usando el método create:

UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

Si es necesario, puedes pasar un argumento $mimeType al método que defina explícitamente el tipo MIME que debería ser devuelto por el archivo:

UploadedFile::fake()->create('document.pdf', $sizeInKilobytes, 'application/pdf');

Aserciones disponibles

Aserciones de respuesta

Laravel proporciona una variedad de métodos de aserción personalizados para tus pruebas funcionales de PHPUnit. Estas aserciones pueden ser accedidas en la respuesta que es retornada por los métodos de prueba json, get, post, put y delete:

assertCookie

Comprueba que la respuesta contenga el cookie dado:

$response->assertCookie($cookieName, $value = null);

assertCookieExpired

Comprueba que la respuesta contenga el cookie dado y que esté vencido:

$response->assertCookieExpired($cookieName);

assertCookieNotExpired

Comprueba que la respuesta contenga la cookie dada y que no haya expirado:

$response->assertCookieNotExpired($cookieName);

assertCookieMissing

Comprueba que la respuesta no contenga el cookie dado:

$response->assertCookieMissing($cookieName);

assertCreated

Comprueba que la respuesta tiene un código de estado 201:

$response->assertCreated();

assertDontSee

Comprueba que la cadena dada no esté contenida dentro de la respuesta:

$response->assertDontSee($value);

assertDontSeeText

Comprueba que la cadena dada no esté contenida dentro del texto de la respuesta:

$response->assertDontSeeText($value);

assertExactJson

Comprueba que la respuesta contenga una coincidencia exacta de los datos JSON dados:

$response->assertExactJson(array $data);

assertForbidden

Comprueba que la respuesta tenga un código de estado «prohibido»:

$response->assertForbidden();

assertHeader

Comprueba que el encabezado dado esté presente en la respuesta:

$response->assertHeader($headerName, $value = null);

assertHeaderMissing

Comprueba que el encabezado dado no esté presente en la respuesta:

$response->assertHeaderMissing($headerName);

assertJson

Comprueba que la respuesta contenga los datos JSON dados:

$response->assertJson(array $data, $strict = false);

assertJsonCount

Comprueba que la respuesta JSON tenga un arreglo con el número esperado de elementos en la llave dada:

$response->assertJsonCount($count, $key = null);

assertJsonFragment

Comprueba que la respuesta contenga el fragmento JSON dado:

$response->assertJsonFragment(array $data);

assertJsonMissing

Comprueba que la respuesta no contenga el fragmento JSON dado:

$response->assertJsonMissing(array $data);

assertJsonMissingExact

Comprueba que la respuesta no contenga el fragmento exacto JSON:

$response->assertJsonMissingExact(array $data);

assertJsonMissingValidationErrors

Comprueba que la respuesta no contenga errores de validación JSON para la llaves dadas:

$response->assertJsonMissingValidationErrors($keys);

assertJsonPath

Comprueba que la respuesta contenga los datos dados en una ruta específica:

$response->assertJsonPath($path, array $data, $strict = false);

assertJsonStructure

Comprueba que la respuesta tenga una estructura JSON dada:

$response->assertJsonStructure(array $structure);

assertJsonValidationErrors

Comprueba que la respuesta tenga los errores de validación JSON dados:

$response->assertJsonValidationErrors(array $data);

assertLocation

Comprueba que la respuesta tenga el valor URI dado en el encabezado Location:

$response->assertLocation($uri);

assertNoContent

Comprueba que la respuesta tenga el código de estado dado sin contenido.

$response->assertNoContent($status = 204);

assertNotFound

Comprueba que la respuesta tenga un código de estado «no encontrado»:

$response->assertNotFound();

assertOk

Comprueba que la respuesta tenga un código de estado 200:

$response->assertOk();

assertPlainCookie

Comprueba que la respuesta contenga el cookie dado (desencriptado):

$response->assertPlainCookie($cookieName, $value = null);

assertRedirect

Comprueba que la respuesta es una redirección a una URI dada:

$response->assertRedirect($uri);

assertSee

Comprueba que la cadena dada esté contenida dentro de la respuesta:

$response->assertSee($value);

assertSeeInOrder

Comprueba que las cadenas dadas estén en orden dentro de la respuesta:

$response->assertSeeInOrder(array $values);

assertSeeText

Comprueba que la cadena dada esté contenida dentro del texto de la respuesta:

$response->assertSeeText($value);

assertSeeTextInOrder

Comprueba que las cadenas dadas estén en orden dentro del texto de respuesta:

$response->assertSeeTextInOrder(array $values);

assertSessionHas

Comprueba que la sesión contenga la porción dada de datos:

$response->assertSessionHas($key, $value = null);

assertSessionHasInput

Comprueba que la sesión tiene un valor dado en los datos del arreglo proporcionado:

$response->assertSessionHasInput($key, $value = null);

assertSessionHasAll

Comprueba que la sesión tenga una lista dada de valores:

$response->assertSessionHasAll(array $data);

assertSessionHasErrors

Comprueba que la sesión contenga un error para los campos dados en $keys. Si $keys es un arreglo asociativo, comprueba que la sesión contenga un mensaje de error específico (value) para cada campo (key):

$response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default');

assertSessionHasErrorsIn

Comprueba que la sesión contenga un error para los campos dados en $keys, dentro de un paquete de error específico. Si $keys es un arreglo asociativo, comprueba que la sesión contenga un mensaje de error específico (value) para cada campo (key), dentro del paquete de error:

$response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null);

assertSessionHasNoErrors

Comprueba que la sesión no contenga errores:

$response->assertSessionHasNoErrors();

assertSessionDoesntHaveErrors

Comprueba que la sesión no contenga errores para las llaves dadas:

$response->assertSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default');

assertSessionMissing

Comprueba que la sesión no contenga la llave dada:

$response->assertSessionMissing($key);

assertStatus

Comprueba que la respuesta tenga un código dado:

$response->assertStatus($code);

assertSuccessful

Comprueba que la respuesta tenga un código de estado de éxito (>= 200 y < 300):

$response->assertSuccessful();

assertUnauthorized

Comprueba que la respuesta tiene un código de estado sin autorización (401):

$response->assertUnauthorized();

assertViewHas

Comprueba que la vista de la respuesta dada contiene los valores indicados:

$response->assertViewHas($key, $value = null);

assertViewHasAll

Comprueba que la vista de la respuesta tiene una lista de datos:

$response->assertViewHasAll(array $data);

assertViewIs

Comprueba que la vista dada fue retornada por la ruta:

$response->assertViewIs($value);

assertViewMissing

Comprueba que a la vista de la respuesta le está faltando una porción de datos enlazados:

$response->assertViewMissing($key);

Aserciones de autenticación

Laravel también proporciona una variedad de aserciones relacionadas con la autenticación para tus pruebas funcionales de PHPUnit:

Método Descripción
$this->assertAuthenticated($guard = null); Comprueba que el usuario está autenticado.
$this->assertGuest($guard = null); Comprueba que el usuario no está autenticado.
$this->assertAuthenticatedAs($user, $guard = null); Comprueba que el usuario dado está autenticado.
$this->assertCredentials(array $credentials, $guard = null); Comprueba que las credenciales dadas son válidas.
$this->assertInvalidCredentials(array $credentials, $guard = null); Comprueba que las credenciales dadas no son válidas.

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Pruebas: Primeros Pasos - Documentación de Laravel 6 Lección siguiente Pruebas de consola - Documentación de Laravel 6