<? phpukraine ДОКУМЕНТАЦІЯ
⌕Пошук по платформі
Документація українською

Переклад офіційної документації українською. Кожен розділ показує стан готовності: недоперекладене позначене відкрито, а не приховане.

ГЛИБШЕ · ПЕРЕКЛАДЕНО оновлено 30 вересня 2026

Архітектурні тести · Pest

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

Ось приклад того, як можна описати архітектурне правило:

arch()
    ->expect('App')
    ->toUseStrictTypes()
    ->not->toUse(['die', 'dd', 'dump']);

arch()
    ->expect('App\Models')
    ->toBeClasses()
    ->toExtend('Illuminate\Database\Eloquent\Model')
    ->toOnlyBeUsedIn('App\Repositories')
    ->ignoring('App\Models\User');

arch()
    ->expect('App\Http')
    ->toOnlyBeUsedIn('App\Http');
    
arch()
    ->expect('App\*\Traits')
    ->toBeTraits();

arch()->preset()->php();
arch()->preset()->security()->ignoring('md5');

Тепер розберемо методи й модифікатори, доступні для архітектурного тестування. У цьому розділі ви дізнаєтесь про:

  • Очікування: дають змогу описувати точні архітектурні правила.
  • Пресети: дають змогу використовувати наперед визначені набори таких правил.
  • Модифікатори: щоб виключити або проігнорувати певні типи файлів, класи, функції чи рядки коду.

Очікування

Точні очікування дають змогу описати конкретні архітектурні правила для вашого застосунку. Ось доступні очікування:

toBeAbstract()

Метод toBeAbstract() перевіряє, що всі класи в заданому просторі імен абстрактні.

arch('app')
    ->expect('App\Models')
    ->toBeAbstract();

toBeClasses()

Метод toBeClasses() перевіряє, що всі файли в заданому просторі імен є класами.

arch('app')
    ->expect('App\Models')
    ->toBeClasses();

toBeEnums()

Метод toBeEnums() перевіряє, що всі файли в заданому просторі імен є переліками (enum).

arch('app')
    ->expect('App\Enums')
    ->toBeEnums();

toBeIntBackedEnums()

Метод toBeIntBackedEnums() перевіряє, що всі переліки в заданому просторі імен мають цілочисельний backing-тип.

arch('app')
    ->expect('App\Enums')
    ->toBeIntBackedEnums();

toBeInterfaces()

Метод toBeInterfaces() перевіряє, що всі файли в заданому просторі імен є інтерфейсами.

arch('app')
    ->expect('App\Contracts')
    ->toBeInterfaces();

toBeInvokable()

Метод toBeInvokable() перевіряє, що всі файли в заданому просторі імен викликні (invokable).

arch('app')
    ->expect('App\Actions')
    ->toBeInvokable();

toBeTraits()

Метод toBeTraits() перевіряє, що всі файли в заданому просторі імен є трейтами.

arch('app')
    ->expect('App\Concerns')
    ->toBeTraits();

toBeFinal()

Метод toBeFinal() перевіряє, що всі класи в заданому просторі імен позначені як final.

arch('app')
    ->expect('App\ValueObjects')
    ->toBeFinal();

Зауважте, що це очікування зазвичай поєднують із модифікатором classes(), щоб перевірити, що всі класи в заданому просторі імен фінальні.

arch('app')
    ->expect('App')
    ->classes()
    ->toBeFinal();

toBeReadonly()

Метод toBeReadonly() перевіряє, що певні класи незмінні й не можуть бути модифіковані під час виконання.

arch('app')
    ->expect('App\ValueObjects')
    ->toBeReadonly();

Зауважте, що це очікування зазвичай поєднують із модифікатором classes(), щоб перевірити, що всі класи в заданому просторі імен readonly.

arch('app')
    ->expect('App')
    ->classes()
    ->toBeReadonly();

toBeStringBackedEnums()

Метод toBeStringBackedEnums() перевіряє, що всі переліки в заданому просторі імен мають рядковий backing-тип.

arch('app')
    ->expect('App\Enums')
    ->toBeStringBackedEnums();

toBeUsed()

Модифікатор not у поєднанні з методом toBeUsed() дає змогу переконатися, що певні класи або функції не використовуються у вашому застосунку.

arch('globals')
    ->expect(['dd', 'dump'])
    ->not->toBeUsed();

arch('facades')
    ->expect('Illuminate\Support\Facades')
    ->not->toBeUsed();

toBeUsedIn()

Поєднавши модифікатор not із методом toBeUsedIn(), можна заборонити використання конкретних класів і функцій у заданому просторі імен.

arch('globals')
    ->expect('request')
    ->not->toBeUsedIn('App\Domain');

arch('globals')
    ->expect('Illuminate\Http')
    ->not->toBeUsedIn('App\Domain');

toExtend()

Метод toExtend() перевіряє, що всі класи в заданому просторі імен успадковують конкретний клас.

arch('app')
    ->expect('App\Models')
    ->toExtend('Illuminate\Database\Eloquent\Model');

toExtendNothing()

Метод toExtendNothing() перевіряє, що всі класи в заданому просторі імен не успадковують жодного класу.

arch('app')
    ->expect('App\ValueObjects')
    ->toExtendNothing();

toImplement()

Метод toImplement() перевіряє, що всі класи в заданому просторі імен реалізують конкретний інтерфейс.

arch('app')
    ->expect('App\Jobs')
    ->toImplement('Illuminate\Contracts\Queue\ShouldQueue');

toImplementNothing()

Метод toImplementNothing() перевіряє, що всі класи в заданому просторі імен не реалізують жодного інтерфейсу.

arch('app')
    ->expect('App\ValueObjects')
    ->toImplementNothing();

toHaveMethodsDocumented()

Метод toHaveMethodsDocumented() перевіряє, що всі методи в заданому просторі імен задокументовані.

arch('app')
    ->expect('App')
    ->toHaveMethodsDocumented();

toHavePropertiesDocumented()

Метод toHavePropertiesDocumented() перевіряє, що всі властивості в заданому просторі імен задокументовані.

arch('app')
    ->expect('App')
    ->toHavePropertiesDocumented();

toHaveAttribute()

Метод toHaveAttribute() перевіряє, що певний клас має конкретний атрибут.

arch('app')
    ->expect('App\Console\Commands')
    ->toHaveAttribute('Symfony\Component\Console\Attribute\AsCommand');

toHaveFileSystemPermissions()

Метод toHaveFileSystemPermissions() перевіряє, що всі файли в заданому просторі імен мають конкретні права доступу у файловій системі.

arch('app')
    ->expect('App')
    ->not->toHaveFileSystemPermissions('0777');

toHaveLineCountLessThan()

Метод toHaveLineCountLessThan() перевіряє, що всі файли в заданому просторі імен мають менше рядків, ніж вказане значення.

arch('app')
    ->expect('App\Models')
    ->toHaveLineCountLessThan(100);

toHaveMethod()

Метод toHaveMethod() перевіряє, що певний клас має конкретний метод.

arch('app')
    ->expect('App\Http\Controllers\HomeController')
    ->toHaveMethod('index');

toHaveMethods()

Метод toHaveMethods() перевіряє, що певний клас має конкретні методи.

arch('app')
    ->expect('App\Http\Controllers\HomeController')
    ->toHaveMethods(['index', 'show']);

toHavePrivateMethodsBesides()

Метод toHavePrivateMethodsBesides() перевіряє, що певний клас не має жодних приватних методів, окрім вказаних.

arch('app')
    ->expect('App\Services\PaymentService')
    ->not->toHavePrivateMethodsBesides(['doPayment']);

toHavePrivateMethods()

Метод toHavePrivateMethods() перевіряє, що певний клас не має жодних приватних методів.

arch('app')
    ->expect('App\Services\PaymentService')
    ->not->toHavePrivateMethods();

toHaveProtectedMethodsBesides()

Метод toHaveProtectedMethodsBesides() перевіряє, що певний клас не має жодних захищених методів, окрім вказаних.

arch('app')
    ->expect('App\Services\PaymentService')
    ->not->toHaveProtectedMethodsBesides(['doPayment']);

toHaveProtectedMethods()

Метод toHaveProtectedMethods() перевіряє, що певний клас не має жодних захищених методів.

arch('app')
    ->expect('App\Services\PaymentService')
    ->not->toHaveProtectedMethods();

toHavePublicMethodsBesides()

Метод toHavePublicMethodsBesides() перевіряє, що певний клас не має жодних публічних методів, окрім вказаних.

arch('app')
    ->expect('App\Services\PaymentService')
    ->not->toHavePublicMethodsBesides(['charge', 'refund']);

toHavePublicMethods()

Метод toHavePublicMethods() перевіряє, що певний клас не має жодних публічних методів.

arch('app')
    ->expect('App\Services\PaymentService')
    ->not->toHavePublicMethods();

toHavePrefix()

Метод toHavePrefix() перевіряє, що всі файли в заданому просторі імен мають конкретний префікс.

arch('app')
    ->expect('App\Helpers')
    ->not->toHavePrefix('Helper');

toHaveSuffix()

Метод toHaveSuffix() перевіряє, що всі файли в заданому просторі імен мають конкретний суфікс.

arch('app')
    ->expect('App\Http\Controllers')
    ->toHaveSuffix('Controller');

toHaveConstructor()

Метод toHaveConstructor() перевіряє, що всі файли в заданому просторі імен мають метод __construct.

arch('app')
    ->expect('App\ValueObjects')
    ->toHaveConstructor();

toHaveDestructor()

Метод toHaveDestructor() перевіряє, що всі файли в заданому просторі імен мають метод __destruct.

arch('app')
    ->expect('App\ValueObjects')
    ->toHaveDestructor();

toOnlyImplement()

Метод toOnlyImplement() перевіряє, що певні класи реалізують лише вказані інтерфейси.

arch('app')
    ->expect('App\Responses')
    ->toOnlyImplement('Illuminate\Contracts\Support\Responsable');

toOnlyUse()

Метод toOnlyUse() гарантує, що певні класи використовують лише вказані функції або класи. Наприклад, так можна перевірити, що ваші моделі залишаються компактними й залежать винятково від простору імен Illuminate\Database, а не, скажімо, відправляють завдання в чергу чи події.

arch('models')
    ->expect('App\Models')
    ->toOnlyUse('Illuminate\Database');

toOnlyBeUsedIn()

Метод toOnlyBeUsedIn() дає змогу обмежити використання конкретного класу або набору класів лише певними частинами застосунку. Наприклад, цим методом можна підтвердити, що ваші моделі використовуються тільки репозиторіями, а не контролерами чи сервіс-провайдерами.

arch('models')
    ->expect('App\Models')
    ->toOnlyBeUsedIn('App\Repositories');

toUse()

Поєднавши модифікатор not із методом toUse(), ви вказуєте, що файли в заданому просторі імен не повинні використовувати конкретні функції або класи.

arch('globals')
    ->expect('App\Domain')
    ->not->toUse('request');

arch('globals')
    ->expect('App\Domain')
    ->not->toUse('Illuminate\Http');

toUseStrictEquality()

Метод toUseStrictEquality() перевіряє, що всі файли в заданому просторі імен використовують строге порівняння. Інакше кажучи, що замість оператора == застосовується ===.

arch('models')
    ->expect('App')
    ->toUseStrictEquality();

Або, якщо вам натомість потрібно перевірити, що всі файли в заданому просторі імен не використовують строге порівняння, скористайтеся модифікатором not.

arch('models')
    ->expect('App')
    ->not->toUseStrictEquality();

toUseTrait()

Метод toUseTrait() перевіряє, що всі файли в заданому просторі імен використовують конкретний трейт.

arch('models')
    ->expect('App\Models')
    ->toUseTrait('Illuminate\Database\Eloquent\SoftDeletes');

toUseTraits()

Метод toUseTraits() перевіряє, що всі файли в заданому просторі імен використовують конкретні трейти.

arch('models')
    ->expect('App\Models')
    ->toUseTraits(['Illuminate\Database\Eloquent\SoftDeletes', 'App\Concerns\CustomTrait']);

toUseNothing()

Якщо потрібно вказати, що певні простори імен або класи не повинні мати жодних залежностей, скористайтеся методом toUseNothing().

arch('value objects')
    ->expect('App\ValueObjects')
    ->toUseNothing();

toUseStrictTypes()

Метод toUseStrictTypes() перевіряє, що всі файли в заданому просторі імен використовують строгі типи.

arch('app')
    ->expect('App')
    ->toUseStrictTypes();

Пресети

Писати архітектурні очікування з нуля буває довго, особливо на початку нового проєкту, коли ви просто хочете переконатися, що базові архітектурні правила виконуються.

Пресети - це наперед визначені набори точних очікувань, якими можна перевіряти архітектуру застосунку.

php

Пресет php - це наперед визначений набір очікувань, який підходить будь-якому PHP-проєкту. Він не привʼязаний до жодного фреймворку чи бібліотеки.

Він забороняє використання die, var_dump і подібних функцій, а також перевіряє, що ви не використовуєте застарілі функції PHP.

arch()->preset()->php();

Усі очікування, що входять до пресету php, можна знайти в нашому початковому коді.

security

Пресет security - це наперед визначений набір очікувань, який підходить будь-якому PHP-проєкту. Він не привʼязаний до жодного фреймворку чи бібліотеки.

Він перевіряє, що ви не використовуєте код, який може призвести до вразливостей у безпеці, наприклад eval, md5 і подібні функції.

arch()->preset()->security();

Усі очікування, що входять до пресету security, можна знайти в нашому початковому коді.

laravel

Пресет laravel - це наперед визначений набір очікувань для проєктів на Laravel.

Він перевіряє, що структура вашого проєкту дотримується відомих домовленостей Laravel: наприклад, що контролери мають публічними методами лише index, show, create, store, edit, update, destroy і завжди мають суфікс Controller, і так далі.

arch()->preset()->laravel();

Усі очікування, що входять до пресету laravel, можна знайти в нашому початковому коді.

strict

Пресет strict - це наперед визначений набір очікувань, який підходить будь-якому PHP-проєкту. Він не привʼязаний до жодного фреймворку чи бібліотеки.

Він перевіряє, що в усіх файлах увімкнено строгі типи, що всі класи фінальні, і не тільки.

arch()->preset()->strict();

Усі очікування, що входять до пресету strict, можна знайти в нашому початковому коді.

relaxed

Пресет relaxed - це наперед визначений набір очікувань, який підходить будь-якому PHP-проєкту. Він не привʼязаний до жодного фреймворку чи бібліотеки.

Він протилежний пресету strict: перевіряє, що в файлах не використовуються строгі типи, що класи не фінальні, і так далі.

arch()->preset()->relaxed();

Усі очікування, що входять до пресету relaxed, можна знайти в нашому початковому коді.

custom

Зазвичай створювати custom-пресет не потрібно, бо точні очікування можна описати методом arch(). Але якщо вам хочеться мати власний пресет, визначте його методом custom.

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

pest()->presets()->custom('ddd', function () {
    return [
        expect('Infrastructure')->toOnlyBeUsedIn('Application'),
        expect('Domain')->toOnlyBeUsedIn('Application'),
    ];
});

Усередині методу custom вам доступні простори імен застосунку за PSR-4 у першому аргументі колбека вашого замикання.

pest()->presets()->custom('silex', function (array $userNamespaces) {
    var_dump($userNamespaces); // array(1) { [0]=> string(3) "App" }
    return [
        expect($userNamespaces)->toBeArray(),
    ];
});

Далі власний пресет використовується так: до методу preset() додається виклик з назвою пресету.

arch()->preset()->silex();

Шаблони (wildcards)

Починаючи з Pest 3.8, у метод expect() можна передавати шаблони, щоб зіставляти код у кількох просторах імен. Наприклад, якщо потрібно перевірити, що весь код у будь-якій підтеці Traits містить трейти:

arch()
    ->expect('App\*\Traits') // Увесь код у будь-якому просторі імен App\*\Traits, наприклад App\Models\Traits тощо.
    ->toBeTraits();

arch()
    ->expect('App\*\*\Traits') // Увесь код у будь-якому просторі імен App\*\*\Traits, наприклад App\A\B\Traits, App\C\D\Traits тощо.
    ->toBeTraits();

Модифікатори

Іноді потрібно застосувати очікування, але виключити з нього певні типи файлів або проігнорувати певні класи, функції чи конкретні рядки коду. Для цього є такі методи:

ignoring()

Описуючи архітектурні правила, методом ignoring() можна виключити простори імен або класи, які інакше потрапили б під дію правила.

arch()
    ->preset()
    ->php()
    ->ignoring('die');

arch()
    ->expect('Illuminate\Support\Facades')
    ->not->toBeUsed()
    ->ignoring('App\Providers');

Часом певні компоненти не варто вважати «залежностями», бо вони є частиною стандартної бібліотеки PHP. Щоб налаштувати, що саме вважати «нативним» кодом, і виключити його під час тестування, Pest дає змогу вказати, що ігнорувати.

Наприклад, якщо ви не хочете вважати Laravel «залежністю», викличте метод arch() у функції beforeEach() і відкиньте весь код у просторі імен «Illuminate». Так ви зосередитеся лише на справжніх залежностях свого застосунку.

// tests/Pest.php
pest()->beforeEach(function () {
    $this->arch()->ignore([
        'Illuminate',
    ])->ignoreGlobalFunctions();
});

classes()

Модифікатор classes() обмежує очікування лише класами.

arch('app')
    ->expect('App')
    ->classes()
    ->toBeFinal();

enums()

Модифікатор enums() обмежує очікування лише переліками.

arch('app')
    ->expect('App\Models')
    ->enums()
    ->toOnlyBeUsedIn('App\Models');

interfaces()

Модифікатор interfaces() обмежує очікування лише інтерфейсами.

arch('app')
    ->expect('App')
    ->interfaces()
    ->toExtend('App\Contracts\Contract');

traits()

Модифікатор traits() обмежує очікування лише трейтами.

arch('app')
    ->expect('App')
    ->traits()
    ->toExtend('App\Traits\Trait');

extending()

Модифікатор extending() обмежує очікування лише класами або інтерфейсами, які успадковують заданий клас.

arch('app')
    ->expect('App')
    ->extending(Model::class)
    ->toUseTrait(HasFactory::class);

implementing()

Модифікатор implementing() обмежує очікування лише класами, які реалізують заданий інтерфейс.

arch('app')
    ->expect('App')
    ->implementing(ShouldQueue::class)
    ->toUseTrait(Dispatchable::class);

using()

Модифікатор using() обмежує очікування лише класами, які використовують заданий трейт.

arch('app')
    ->expect('App')
    ->using(HasFactory::class)
    ->toExtend(Model::class);

У цьому розділі ви дізналися, як виконувати архітектурне тестування й перевіряти, що архітектура вашого застосунку чи бібліотеки відповідає заданому набору вимог. Далі: чи думали ви колись, як тестувати продуктивність свого коду? Розглянемо стрес-тестування.

Стан перекладу

Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.

48%
Готовності
0
У роботі
12
Ще не перекладено
Глосарій термінів