Урок 12: Тестирование в Laravel. Unit-тесты, HTTP-тесты, работа с базой данных

Мы прошли уже 11 уроков. Научились работать с роутами, контроллерами, базами данных, Blade, Eloquent. Теперь пришло время поговорить о важнейшей части разработки, это тестировании. В этом уроке я расскажу, как писать тесты в Laravel, начиная с простых Unit-тестов и заканчивая сложными HTTP-тестами. Мы разберемся с PHPUnit, тестированием роутов, контроллеров, баз данных и даже напишем несколько практических примеров. \

Представь, что ты построил дом, но не проверил, насколько прочны его стены. Тестирование это именно та проверка. Оно помогает:

  • Находить ошибки до того, как их увидят пользователи.
  • Убедиться, что изменения в коде не сломали существующие функции.
  • Сэкономить время на ручную проверку.
  • Повысить уверенность в своем коде.

Laravel предоставляет мощные инструменты для тестирования «из коробки» и сегодня мы научимся ими пользоваться.

Настройка окружения для тестирования

Перед началом убедись, что у тебя установлен PHPUnit. В Laravel он уже включен в зависимости.
Чтобы запустить тесты, используй команду:

bash
php artisan test

Все тесты хранятся в директории tests/. По умолчанию там есть два файла:

  • Unit/ExampleTest.php для Unit-тестов.
  • Feature/ExampleTest.php для функциональных тестов.

Написание Unit-тестов с PHPUnit

Unit-тесты проверяют отдельные «юниты» кода, например методы классов.

Пример: Простой тест

Допустим, у нас есть класс Calculator с методом add(), который складывает два числа.
Создадим его в app/Calculator.php:

php
namespace App; 

class Calculator 
{ 
    public function add($a, $b) 
    { 
        return $a + $b; 
    } 
}

Теперь напишем тест для этого класса. Создай файл tests/Unit/CalculatorTest.php:

php
namespace Tests\Unit; 

use App\Calculator; 
use PHPUnit\Framework\TestCase; 

class CalculatorTest extends TestCase 
{ 
    public function test_add_numbers() 
    { 
        $calculator = new Calculator(); 
        $result = $calculator->add(2, 3); 
        
        $this->assertEquals(5, $result); // Проверяем, что 2 + 3 = 5 
    } 
}

Запусти тест:

bash
php artisan test --filter CalculatorTest

Если видишь зеленую надпись OK, значит, все работает!

Основные методы PHPUnit

  • assertEquals($expected, $actual) — проверяет равенство значений.
  • assertTrue($condition) — проверяет, что условие истинно.
  • assertFalse($condition) — проверяет, что условие ложно.
  • assertContains($needle, $array) — проверяет наличие элемента в массиве.

Практическая задача:
Напиши метод subtract() в классе Calculator и создай для него Unit-тест.

Тестирование роутов и контроллеров

В Laravel можно тестировать не только классы, но и маршруты с контроллерами.

Пример: Тестирование GET-запроса

Допустим, у нас есть роут:

php
Route::get('/welcome', function () { 
    return view('welcome'); 
});

Создадим тест в tests/Feature/RoutingTest.php:

php
namespace Tests\Feature; 

use Tests\TestCase; 

class RoutingTest extends TestCase 
{ 
    public function test_welcome_route() 
    { 
        $response = $this->get('/welcome'); 
        $response->assertStatus(200); // Проверяем статус 200 (OK) 
        $response->assertViewIs('welcome'); // Проверяем, что возвращается view welcome 
    } 
}

Пример: Тестирование контроллера

Предположим, у нас есть контроллер UserController с методом index(), который возвращает список пользователей.

Тест в tests/Feature/UserControllerTest.php:

php
namespace Tests\Feature; 

use Tests\TestCase; 

class UserControllerTest extends TestCase 
{ 
    public function test_user_index_returns_json() 
    { 
        $response = $this->getJson('/api/users'); 
        $response->assertStatus(200); 
        $response->assertJsonStructure(['data' => []]); // Проверяем структуру JSON 
    } 
}

Практическая задача:
Создай роут /about, который возвращает view about.blade.php и напиши для него тест.

Тестирование баз данных

Часто нужно проверить, что данные корректно сохраняются в БД. Laravel предоставляет для этого удобные методы.

Пример: Тестирование создания пользователя

Используем фабрику для генерации тестовых данных. Создай фабрику для модели User:

bash
php artisan make:factory UserFactory --model=User

В файле database/factories/UserFactory.php:

php
use App\Models\User; 
use Illuminate\Support\Facades\Hash; 

$factory->define(User::class, function (Faker $faker) { 
    return [ 
        'name' => $faker->name, 
        'email' => $faker->unique()->safeEmail, 
        'password' => Hash::make('password'), 
    ]; 
});

Теперь напишем тест в tests/Feature/UserTest.php:

php
namespace Tests\Feature; 

use App\Models\User; 
use Illuminate\Foundation\Testing\RefreshDatabase; 
use Tests\TestCase; 

class UserTest extends TestCase 
{ 
    use RefreshDatabase; // Автоматически обновляет БД после каждого теста 

    public function test_user_creation() 
    { 
        $user = User::factory()->create(); 
        
        $this->assertDatabaseHas('users', [ 
            'email' => $user->email 
        ]); 
    } 
}

Практическая задача:
Создай модель Post с полями title и content, напиши фабрику и тест для проверки создания поста.

Примеры HTTP-тестов

HTTP-тесты позволяют имитировать запросы к приложению и проверять ответы.

Пример: Тестирование формы входа

Допустим, у нас есть маршрут /login, который принимает email и password.

Тест в tests/Feature/AuthTest.php:

php
namespace Tests\Feature; 

use App\Models\User; 
use Illuminate\Foundation\Testing\RefreshDatabase; 
use Tests\TestCase; 

class AuthTest extends TestCase 
{ 
    use RefreshDatabase; 

    public function test_user_login() 
    { 
        $user = User::factory()->create([ 
            'password' => bcrypt('password123') 
        ]); 

        $response = $this->post('/login', [ 
            'email' => $user->email, 
            'password' => 'password123' 
        ]); 

        $response->assertRedirect('/dashboard'); // Проверяем редирект 
        $this->assertAuthenticatedAs($user); // Проверяем, что пользователь авторизован 
    } 
}

Пример 6: Тестирование Middleware

Проверим, что гость не может попасть на защищенную страницу.

php
public function test_guest_cannot_access_admin() 
{ 
    $response = $this->get('/admin'); 
    $response->assertRedirect('/login'); 
}

Практическая задача:
Создай маршрут /posts, который доступен только аутентифицированным пользователям и напиши тест для проверки доступа.

Итоги 12-го урока

Сегодня мы научились:

  • Писать Unit-тесты с PHPUnit.
  • Тестировать роуты и контроллеры.
  • Работать с тестовой базой данных.
  • Выполнять HTTP-тесты.

Тестирование это навык, который требует практики. Не ленись писать тесты для своих проектов,и ты увидишь, как улучшится качество твоего кода.

Готов погрузиться глубже? Полный курс по Laravel для начинающих

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий