Завантаження публікації
ОГОЛОШЕННЯ

Feature-тести в Laravel: 2–3 перевірки маршрутів, які одразу ловлять поломки

Пояснюємо “happy path” на практиці: як протестувати index/store/update через HTTP-запити, редиректи та запис у базу, щоб CRUD-модуль працював стабільно після будь-яких правок.


Максим Третяк
Максим Третяк
Газета Дейком | 30.12.2025, 19:00 GMT+3; 12:00 GMT-4

Feature-тести (інтеграційні тести) потрібні не “для галочки”, а щоб ти кожного разу не перевіряв модуль руками. Вони імітують реальні дії користувача: зайшов на сторінку списку, відкрив форму, відправив POST, отримав редирект, а запис реально з’явився в базі. Навіть 2–3 тести “happy path” дають різкий приріст надійності: ти одразу бачиш, що маршрути, валідація, контролер і запис у БД працюють разом.

У Laravel найпростіший старт — це php artisan test, а в самих тестах — RefreshDatabase, щоб база для тестів була чистою. Під “happy path” мається на увазі сценарій без помилок: користувач має доступ, відправляє коректні дані, отримує очікувану відповідь. Для першого модуля (Tags/Sections/Resources) цього достатньо, щоб закрити головний ризик: “маршрути не туди ведуть” або “нічого не записується”.

Найкращий набір із 2–3 тестів для CRUD-модуля виглядає так. Перший тест — index відкривається і повертає 200 (або робить редирект на логін, якщо гість). Другий тест — store створює запис: відправили POST з валідними даними, отримали редирект (зазвичай 302) і в базі з’явився рядок. Третій тест — update змінює запис: відправили PUT/PATCH, отримали редирект і в базі оновилось поле. Це найчистіший “скелет” перевірки реального потоку.

Нижче — практичний шаблон під модуль Tags. Навіть якщо ти робиш Resources або Sections, логіка однакова: змінюються лише таблиця, маршрути і поля. Важлива дисципліна: у тесті ти звертаєшся до named routes (route('admin.tags.index')), а не до “жорстких” URL, тоді тести не зламаються, якщо завтра ти змінюватимеш шлях.

php artisan make:test TagRoutesTest

namespace Tests\Feature\Admin;

use Tests\TestCase;

use Illuminate\Foundation\Testing\RefreshDatabase;

use App\Models\User;

use App\Models\Tag;

class TagRoutesTest extends TestCase

{

use RefreshDatabase;

protected function adminUser(): User

{

// Варіант 1 (кращий): factory, якщо у вас вони є

// return User::factory()->create();

// Варіант 2 (якщо factory немає): створити мінімального юзера руками

return User::query()->create([

'name' => 'Test Admin',

'email' => 'admin@test.local',

'password' => bcrypt('password'),

]);

}

public function test_index_page_opens_for_authorized_user(): void

{

$user = $this->adminUser();

// Якщо у вас жорсткий permission middleware — тут треба дати юзеру права.

// Це залежить від вашої реалізації (roles/permissions). Ідея: видати доступ перед запитом.

$resp = $this->actingAs($user)->get(route('admin.tags.index'));

$resp->assertStatus(200);

// Додатково можна перевірити, що сторінка містить заголовок або кнопку "Створити"

// $resp->assertSee('Теги');

}

public function test_store_creates_tag_and_redirects(): void

{

$user = $this->adminUser();

$payload = [

'name' => 'Laravel',

'slug' => 'laravel',

];

$resp = $this->actingAs($user)->post(route('admin.tags.store'), $payload);

$resp->assertStatus(302);

$resp->assertRedirect(route('admin.tags.index'));

$this->assertDatabaseHas('tags', [

'name' => 'Laravel',

'slug' => 'laravel',

]);

}

public function test_update_changes_tag_and_redirects(): void

{

$user = $this->adminUser();

// Якщо є factory:

// $tag = Tag::factory()->create(['name' => 'PHP', 'slug' => 'php']);

// Якщо factory немає:

$tag = Tag::query()->create(['name' => 'PHP', 'slug' => 'php']);

$payload = [

'name' => 'PHP 8',

'slug' => 'php-8',

];

$resp = $this->actingAs($user)->put(route('admin.tags.update', $tag), $payload);

$resp->assertStatus(302);

$resp->assertRedirect(route('admin.tags.index'));

$this->assertDatabaseHas('tags', [

'id' => $tag->id,

'name' => 'PHP 8',

'slug' => 'php-8',

]);

}

}

Як це запускати і що вважати “успіхом”. Запускаєш php artisan test, і тести мають проходити стабільно на чистій тестовій базі. Якщо падає 403, значить ти реально вперся в доступи — і це нормально: тест показав правду. Тоді правильне рішення не “відключити middleware назавжди”, а у helper-методі adminUser() видати потрібні permissions/role так, як це зроблено у вашому проєкті, і вже тоді повторити запит.

Якщо падає 419, значить ти тестуєш форму з CSRF/сесією некоректно або маршрут під web, але ти йдеш якось “не так”. У feature-тестах через post() і actingAs() Laravel зазвичай коректно симулює сесію, тож 419 найчастіше означає, що маршрут під іншим guard або є нестандартна перевірка. Знову ж таки, це корисно: ти бачиш, де реальна точка блокування.

Висновок тут простий: 2–3 feature-тести “happy path” — це мінімальний страховий поліс. Вони швидко ловлять поломки маршрутів, редиректів, контролерів, сервісів і БД-запису. Далі, коли модуль розростеться, ти додаєш негативні кейси (422 на валідацію, 403 на доступ), але стартовий мінімум саме такий: index відкрився, store створив, update оновив.


Максим Третяк — Кореспондент, який спеціалізується на суспільно важливих темах, пише про політику, фінансові ринки та економіку. Він проживає та працює в Україні.

Цей матеріал є частиною розгорнутої теми: Web-програмування, яка охоплює численні цікаві аспекти цієї події. Газета «Дейком» ретельно відстежує події, проводячи перевірку джерел та інформації, щоб забезпечити нашим читачам найбільш точне та актуальне інформування.

Цей матеріал опубліковано 30.12.2025 року о 19:00 GMT+3 Київ; 12:00 GMT-4 Вашингтон, розділ: Освіта, із заголовком: "Feature-тести в Laravel: 2–3 перевірки маршрутів, які одразу ловлять поломки". Якщо в публікації з'являться зміни, про це буде зазначено та описано у кінці публікації.

Читайте щоденну газету та загальну стрічку новин газети Дейком, яка поєднує багато цікавого в понад 40 розділах з усіх куточків світу.


Save
ОГОЛОШЕННЯ

Новини, які можуть Вас зацікавити:

Штатні та позаштатні журналісти газети «Дейком» щодня готують сотні публікацій, щоб читачі отримували найоперативнішу, перевірену й глибоку інформацію. Ми працюємо для тих, хто хоче розуміти суть подій, бачити широку картину та бути на крок попереду.

Останні новини

Вибір редакції