Тестирование приложений Laravel с помощью PHPUnit

Начало работы с PHPUnit

Laravel имеет встроенный фреймворк тестирования - PHPUnit. 

PHPUnit - это наиболее популярный фреймворк для тестирования PHP-кода. Хотя его название наводит на мысль, что он используется только для модульных тестов, он способен на гораздо большее. 

Вообще говоря, он позволяет выполнять два вида тестов: модульные и функциональные (интеграционные). Кроме того, с его помощью можно получить информацию о качестве кода и общем тестовом покрытии проекта.

Модульные и функциональные тесты

Возможно, вам интересно узнать, в чем разница между этими двумя типами тестов. Вот краткий обзор. 

Модульные тесты

Модульные тесты нацелены на небольшие изолированные части кода. В идеале с помощью модульного теста можно протестировать один метод, небольшой фрагмент функциональности, не затрагивая остальную часть приложения (базу данных или сервер).

По сути, юнит-тест выступает в качестве проверки на правильность написания функции и позволяет убедиться, что она выполняет то, что вы от нее хотите. Они могут быть весьма полезны, например, при рефакторинге больших методов

Тесты функций

Когда приложение увеличивается в размерах, важно проводить функциональные тесты для проверки правильности работы и взаимодействия всех его частей. И если это не так, то важно знать, какие части/соединения не работают. 

Для этого мы можем использовать функциональные тесты. В отличие от модульных тестов, функциональные тесты проверяют гораздо более сложную функциональность и часто включают в себя более серьезные настройки, чем просто вызов метода. Они часто проверяют запросы к API или базе данных. 

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

Как писать тесты в Laravel с помощью PHPUnit

В Laravel поддержка тестирования с помощью PHPUnit включена сразу из коробки, а необходимый конфигурационный файл - phpunit.xml - уже настроен для вашего приложения. 

Чтобы начать тестирование, достаточно написать тесты и, возможно, изменить некоторые значения по умолчанию в конфигурации. 

Для Laravel-приложения тесты обычно лежат в папках Tests\\Unit и Tests\\Feature (это можно изменить с помощью файла phpunit.xml). Каждый из них имеет имя {Name}Test.php. 

Для создания нового теста можно воспользоваться командой make:test.

php artisan make:test NameTest

По умолчанию новый тест будет помещен в каталог Tests\/Feature. Чтобы инициализировать юнит-тест, необходимо добавить в конце флаг -unit.   

php artisan make:test NameTest -unit

Для запуска тестов можно воспользоваться командой php artisan test или запустить phpunit из .\/vendor\/bin\/phpunit.

Давайте рассмотрим несколько примеров тестов, чтобы лучше понять, что мы можем сделать.

Пример юнит-теста Laravel

Вот тривиальный автогенерируемый юнит-тест для приложения Laravel.

<?php

пространство имен Tests\\Unit;

use PHPUnit\\Framework\\TestCase;

class ExampleTest extends TestCase

{

    public function test_basic_test()

    {

        $this->assertTrue(true);

    }

}

Внутри теста мы можем утверждать результат работы любого из методов в нашей кодовой базе. Assert имеет множество различных опций - вы можете ознакомиться с ними в документации PHPUnit.

Обычно у нас есть некоторые выходные данные, которые метод должен возвращать при определенных входных данных. Мы импортируем класс метода, вызываем метод и сравниваем ожидаемый результат с результатом метода.

Пример функционального теста Laravel

В функциональных тестах больше подвижных частей, что делает их несколько сложнее. 

Вот пример теста, который проверяет, находится ли сервер в сети: 

<?php

пространство имен Tests\\Feature;

use Illuminate\\Foundation\\Testing\\RefreshDatabase;

use Illuminate\\Foundation\\Testing\\WithoutMiddleware;

use Tests\\TestCase;

class ExampleTest extends TestCase

{

    public function test_a_basic_request()

    {

        $response = $this->get('\/');

        $response->assertStatus(200);

    }

}

Для более сложного примера приведем тест, который проверяет, может ли приложение публиковать сообщения в группе Telegram (предполагается, что функциональность написана и существует в классе). 

<?php

namespace Tests\\Feature;

use App\\Classes\\Telegram\\Telegram;

use App\\Http\\Controllers\\PublicController;

use Illuminate\\Http\\Request;

use PHPUnit\\Framework\\TestCase;

class TelegramTest extends TestCase

{

    public function testTelegramWritingToGroup() 

    {

        $telegram = new Telegram();

        $response = json_decode($telegram->sendCurlMessage("sendMessage",$telegram- >makeArray(env('GROUP_ID'), "Unit test successfully completed", []));

        $this->assertTrue($response->ok);

    }