Подписывайтесь на наш Telegram канал и будьте в курсе всех событий.
Ищете работу? Мы поможем!
Ищете работу? Мы поможем!

HTTP тесты

Вы просматриваете документ для прошлой версии.
Рассмотрите возможность обновления вашего проекта до актуальной версии 11.x. Почему это важно?

Введение

Laravel предоставляет довольно функциональный API для составления HTTP-запросов к вашему приложению и анализа выходных данных. Например, давайте рассмотрим тест ниже:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

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

        $response->assertStatus(200);
    }
}

Метод get делает запрос GET в приложение, в то время как метод assertStatus утверждает, что возвращенный ответ должен иметь заданный HTTP код статуса. В дополнение к этому простому утверждению в Laravel также содержится множество утверждений для инспектирования заголовков ответов, их содержимого, структуры JSON и др.

Сессия / Аутентификация

В Laravel есть несколько хелперов для работы с сессией во время HTTP-тестирования. Во-первых, можно задать данные сессии заданному массиву используя метод withSession. Это полезно для загрузки сессии с данными до отправки запроса вашему приложению:

<?php

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

Конечно, одно из общепринятых использований сессии – поддержание состояния аутентифицированного пользователя. Хелпер actingAs предоставляет простой способ аутентифицировать заданного пользователя как текущего пользователя. Например, можно использовать фабрику моделей, чтобы сгенерировать и аутентифицировать пользователя:

<?php

use App\User;

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

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

Также можно указать какого гварда следует использовать для аутентификации заданного пользователя, передавая имя гварда в качестве второго аргумента методу actingAs:

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

Тестирование JSON API

В Laravel есть несколько хелперов для тестирования JSON API и его ответов. Например, методы json, get, post, put, patch и delete можно использовать, чтобы послать запросы с разными HTTP глаголами. Вы также можете легко передать этим методам данные и заголовки. Для начала напишем тест, чтобы послать запрос POST пользователю /user и затем выдать утверждение, что были возвращены ожидаемые данные:

<?php

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

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

Метод assertJson конвертирует ответ в массив и использует PHPUnit::assertArraySubset для проверки, что заданный массив существует в JSON-ответе, возвращенном приложением. Итак, если у JSON-ответа есть другие свойства, этот тест все еще будет пройден, так как присутствует заданный фрагмент.

Проверка точного соответствия

Если нам нужно проверить, что заданный массив – точное соответствие JSON, возвращенного приложением, следует использовать метод 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(200)
            ->assertExactJson([
                'created' => true,
            ]);
    }
}

Тестирование загрузки файлов

Класс Illuminate\Http\UploadedFile предоставляет метод fake, который можно использовать для генерирования фиктивных файлов или изображений для тестирования. Вместе с методом fake васада Storage это значительно упрощает тестирование загрузки файлов. Например, можно скомбинировать эти две функции, чтобы быстро протестировать форму загрузки аватара:

<?php

namespace Tests\Feature;

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

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

        $response = $this->json('POST', '/avatar', [
            'avatar' => UploadedFile::fake()->image('avatar.jpg')
        ]);

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

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

Настройка фиктивных файлов

При создании файлов методом fake можно указать ширину, высоту и размер изображения, чтобы лучше проверить свои правила валидации:

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

В дополнение к созданию изображений можно создавать файлы любого другого типа используя метод create:

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

Доступные утверждения

Laravel предоставляет множество методов утверждений для ваших PHPUnit-тестов. Доступ к этим утверждениям можно получить в ответе, который был возвращен тестовыми методами json, get, post, put и delete:

Метод Описание
$response->assertStatus($code); Ответ содержит заданный код.
$response->assertRedirect($uri); Ответ - это редирект на заданный URI.
$response->assertHeader($headerName, $value = null); В ответе присутствует заданные заголовок.
$response->assertCookie($cookieName, $value = null); В ответе содержится заданный cookie.
$response->assertPlainCookie($cookieName, $value = null); В ответе содержится заданный cookie (незашифрованный).
$response->assertSessionHas($key, $value = null); В сессии содержится заданный фрагмент данных.
$response->assertSessionHasErrors(array $keys); В сессии содержится ошибка для заданного поля.
$response->assertSessionMissing($key); В сессии не содержится заданный ключ.
$response->assertJson(array $data); В ответе содержатся заданные данные JSON.
$response->assertJsonFragment(array $data); В ответе содержится заданный фрагмент JSON.
$response->assertJsonMissing(array $data); В ответе не содержится заданный фрагмент JSON.
$response->assertExactJson(array $data); В ответе содержится точное совпадение заданных JSON-данных.
$response->assertJsonStructure(array $structure); У ответа есть заданная JSON-структура.
$response->assertViewIs($value); Роутом был возвращен заданный шаблон.
$response->assertViewHas($key, $value = null); Фрагмент данных был передан шалону ответа.