Prečo Pest namiesto PHPUnit?
PHPUnit je solídny základ — Pest na ňom priamo stojí. Pest len pridáva expresívnu vrstvu, ktorá robí testy čitateľnejšie a písanie rýchlejšie. Od Laravelu 11 je Pest predvoleným testovacím frameworkom pri laravel new.
| Aspekt | PHPUnit | Pest |
|---|---|---|
| Syntax | Triedy a metódy | Funkcie it(), test() |
| Assertions | $this->assertEquals() | expect()->toBe() |
| Architecture testy | Nie | Áno, natívne |
| Paralelné spúšťanie | Cez plugin | Zabudované (--parallel) |
| Dataset (DataProvider) | Verbose | Kompaktné with() |
| Laravel integrácia | Manuálna | Automatická (TestCase) |
Inštalácia v Laravel projekte
Laravel 11+ má Pest predkonfigurovaný. Pre staršie projekty alebo clean install:
composer require pestphp/pest pestphp/pest-plugin-laravel --dev
# Inicializácia (vytvorí pest.php konfiguráciu)
./vendor/bin/pest --init
# Spustenie testov
./vendor/bin/pest
# S coverage reportom (vyžaduje Xdebug alebo PCOV)
./vendor/bin/pest --coverage --min=80
Konfigurácia v pest.php:
<?php
// pest.php
uses(Tests\TestCase::class)->in('Feature');
uses(Tests\TestCase::class, Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature');
// Globálny dataset pre reusable test data
dataset('roles', ['admin', 'editor', 'viewer']);
Základná syntax — unit testy
Pest používa dve funkcie: test() pre opisný názov a it() pre anglickú vetu (automaticky pridá „it" na začiatok pri výpise).
// tests/Unit/PriceCalculatorTest.php
test('vypočíta správnu cenu s DPH', function () {
$calculator = new PriceCalculator();
expect($calculator->withVat(100))->toBe(120.0);
});
it('zaokrúhli na 2 desatinné miesta', function () {
$calculator = new PriceCalculator();
expect($calculator->withVat(33.333))->toBe(40.0);
});
// Dataset — spusti test pre viacero vstupov
it('aplikuje správnu sadzbu podľa kategórie', function (string $category, float $rate) {
$calculator = new PriceCalculator();
expect($calculator->vatRate($category))->toBe($rate);
})->with([
'potraviny' => ['food', 0.10],
'štandardné' => ['standard', 0.20],
'knihy' => ['books', 0.10],
]);
Reťazenie expect() — fluent assertions
Silou Pestu sú reťaziteľné assertions. Jeden expect() môže obsahovať desiatky overení na jednom objekte.
it('vracia správne naformátovaný produkt', function () {
$product = Product::factory()->create([
'name' => 'PHP kniha',
'price' => 29.99,
'stock' => 5,
]);
expect($product)
->name->toBe('PHP kniha')
->price->toBeFloat()
->price->toBeGreaterThan(0)
->stock->toBeInt()
->stock->toBeGreaterThanOrEqual(0)
->is_active->toBeTrue()
->deleted_at->toBeNull();
});
// Testovanie výnimiek
it('vyhodí výnimku pri neplatnej cene', function () {
expect(fn() => new Product(['price' => -1]))
->toThrow(InvalidArgumentException::class, 'Cena musí byť kladná');
});
Feature testy — HTTP testovanie v Laraveli
Feature testy simulujú HTTP requesty na vaše routes. V Pest + Laravel máte prístup k celej sade Laravel test helperov.
// tests/Feature/ProductApiTest.php
uses(RefreshDatabase::class);
beforeEach(function () {
// Spúšťa sa pred každým testom v tomto súbore
$this->user = User::factory()->create();
});
it('vracia zoznam produktov pre autentifikovaného používateľa', function () {
Product::factory()->count(3)->create();
$response = $this
->actingAs($this->user)
->getJson('/api/products');
$response
->assertOk()
->assertJsonCount(3, 'data')
->assertJsonStructure([
'data' => [['id', 'name', 'price']],
'meta' => ['total', 'per_page'],
]);
});
it('blokuje prístup bez autentifikácie', function () {
$this->getJson('/api/products')
->assertUnauthorized();
});
it('vytvorí nový produkt', function () {
$this->actingAs($this->user)
->postJson('/api/products', [
'name' => 'Nový produkt',
'price' => 49.99,
])
->assertCreated()
->assertJsonPath('data.name', 'Nový produkt');
$this->assertDatabaseHas('products', ['name' => 'Nový produkt']);
});
Testovanie formulárovej validácie
it('validuje povinné polia pri registrácii', function (string $field, mixed $value, string $error) {
$data = [
'name' => 'Ján Novák',
'email' => 'jan@example.com',
'password' => 'secret123!',
];
$data[$field] = $value;
$this->postJson('/api/register', $data)
->assertUnprocessable()
->assertJsonValidationErrors([$field]);
})->with([
'prázdne meno' => ['name', '', 'name'],
'krátke heslo' => ['password', 'abc', 'password'],
'neplatný e-mail' => ['email', 'nie-email', 'email'],
]);
Architecture testy — automatická kontrola štruktúry kódu
Architecture testy sú unikátnou vlastnosťou Pestu. Automaticky kontrolujú, či kód dodržiava architektonické pravidlá — bez code review na každom PR.
// tests/Architecture/AppTest.php
arch('Controllers nepoužívajú Eloquent priamo')
->expect('App\Http\Controllers')
->not->toUse('Illuminate\Database\Eloquent\Model');
arch('Actions sú finálne triedy')
->expect('App\Actions')
->toBeFinal();
arch('Models rozširujú Eloquent Model')
->expect('App\Models')
->toExtend('Illuminate\Database\Eloquent\Model');
arch('Interfaces sú len v dedikovanom namespace')
->expect('App\Contracts')
->toBeInterfaces();
// Preddefinované pravidlá pre Laravel
arch()->preset()->laravel();
arch()->preset()->security()->ignoring('App\Models');
Mocking a faking v Pest + Laravel
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Queue;
use App\Mail\WelcomeMail;
use App\Jobs\SendWelcomeEmail;
it('odošle uvítací e-mail po registrácii', function () {
Mail::fake();
$this->postJson('/api/register', [
'name' => 'Ján', 'email' => 'jan@test.sk', 'password' => 'heslo1234!',
])->assertCreated();
Mail::assertSent(WelcomeMail::class, function ($mail) {
return $mail->hasTo('jan@test.sk');
});
});
it('zaradí job do fronty bez skutočného spracovania', function () {
Queue::fake();
$this->postJson('/api/register', [...])
->assertCreated();
Queue::assertPushed(SendWelcomeEmail::class);
});
Paralelné spúšťanie testov
Pest 3 má zabudované paralelné spúšťanie — každý worker dostane vlastnú databázu, takže testy sa navzájom neovplyvňujú.
# Paralelné spúšťanie (využije všetky CPU jadrá)
./vendor/bin/pest --parallel
# Určenie počtu workerov
./vendor/bin/pest --parallel --processes=4
phpunit.xml nastavené DB_DATABASE=:memory: alebo Pest automaticky vytvorí test_N databázy. Externe zdieľané zdroje (Redis, súborový systém) musia byť v testoch izolované pomocou faker alebo dočasných prefixov.
Coverage report a minimálne pokrytie
Pest integruje code coverage priamo — pre CI/CD môžete nastaviť minimálne pokrytie ako podmienku úspešného buildu.
# Vyžaduje Xdebug 3+ alebo PCOV rozšírenie
./vendor/bin/pest --coverage --min=80
# HTML report
./vendor/bin/pest --coverage-html=coverage/
# GitHub Actions integrácia
- name: Run Pest tests with coverage
run: ./vendor/bin/pest --coverage --min=80 --coverage-clover=coverage.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: coverage.xml
Kompletný CI/CD pipeline pre testovanie
# .github/workflows/tests.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
env:
MYSQL_DATABASE: test_db
MYSQL_ROOT_PASSWORD: secret
ports: ['3306:3306']
steps:
- uses: actions/checkout@v4
- name: Setup PHP 8.4
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: pdo_mysql, pcov
coverage: pcov
- name: Install dependencies
run: composer install --no-interaction --prefer-dist
- name: Copy .env
run: cp .env.testing .env.testing.local
- name: Run tests
run: ./vendor/bin/pest --parallel --coverage --min=80
env:
DB_HOST: 127.0.0.1
DB_DATABASE: test_db
DB_USERNAME: root
DB_PASSWORD: secret
Záver: Pest ako štandard pre Laravel testovanie v roku 2026
Pest 3 + Architecture testy + paralelné spúšťanie je kombinácia, ktorá dramaticky zlepšuje kvalitu kódu bez spomaľovania vývoja. Expresívna syntax znižuje bariéru pre písanie testov — vývojári testy píšu chętnejšie, keď sa čítajú ako dokumentácia.
Ak ešte váš Laravel projekt nemá testy, začnite s Feature testami pre kritické endpointy a Architecture testami pre dodržiavanie konvencií. Obe je možné pridať postupne bez rewrite existujúceho kódu.
Chcete zavedenie testovania do existujúceho Laravel projektu?
Pomôžem vám nastaviť Pest, napísať prvé testy pre kritické časti aplikácie a zaviesť CI/CD pipeline. Odpoveď do 24 hodín.
Nezáväzný dopyt