Stručně: PHPUnit je standardní nástroj pro automatické testování kódu PHP; Pest je framework, který na něm staví, s kratším zápisem. Aktuální je PHPUnit 13 (od února 2026, od PHP 8.4), Pest je ve verzi 5. Automatické testy neuzavřou bezpečnostní zranitelnosti v samotném PHP, ale činí aktualizace plánovatelnými: po PHP2Shell a před koncem podpory PHP 8.2 dne 31. 12. 2026 je to rozhodující výhoda.
Proč testovat kód PHP?
Pro vedení firmy lze přínos shrnout jednou větou: testy činí změny levnějšími a bezpečnějšími. Automatický test za pár sekund ověří, zda funkce stále dělá to, co má, například zda nákupní košík správně počítá nebo zda přihlášení odmítne špatná hesla. Bez testů to kontroluje člověk ručně, nebo nikdo.
Rozdíl je zvlášť patrný u aktualizací. Pokud je nutné PHP kvůli kritické zranitelnosti rychle aktualizovat, mnoho provozovatelů váhá, protože se bojí chyb v e-shopu nebo zákaznickém portálu. S testovací sadou proběhne aktualizace nejprve v testovacím prostředí, testy ukážou problémy a teprve poté se jde naostro.
PHPUnit: standard pro testy v PHP
PHPUnit vychází každý rok v únoru v nové hlavní verzi. Každá verze vyžaduje minimální verzi PHP a zhruba dva roky dostává opravy chyb. Podle phpunit.de platí:
| PHPUnit | Vydáno | Požadavek na PHP | Opravy chyb do |
|---|---|---|---|
| 13 | 6. 2. 2026 | od PHP 8.4 | 4. 2. 2028 |
| 12 | 7. 2. 2025 | od PHP 8.3 | 5. 2. 2027 |
| 11 | 2. 2. 2024 | od PHP 8.2 | 6. 2. 2026 |
| 10 | 3. 2. 2023 | od PHP 8.1 | 7. 2. 2025 |
Tabulka ukazuje praktickou souvislost: projekt, který ještě používá PHPUnit 10, většinou běží také na staré verzi PHP. Testovací nástroje a verzi PHP je vhodné zvyšovat společně. PHPUnit se obvykle instaluje přes Composer jako vývojová závislost.
První test s PHPUnit
Test je třída, která dědí z PHPUnit\Framework\TestCase. Testovací metody jsou veřejné a začínají na test, případně se označí atributem #[Test]. Příklad ověřuje jednoduchou funkci pro výpočet ceny:
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
final class BruttopreisTest extends TestCase
{
public static function preise(): array
{
return [
'Normalsatz' => [10000, 19, 11900],
'Ermäßigt' => [10000, 7, 10700],
'Null bleibt Null' => [0, 19, 0],
];
}
#[DataProvider('preise')]
public function testBruttopreisInCent(int $netto, int $satz, int $erwartet): void
{
$this->assertSame($erwartet, bruttopreis($netto, $satz));
}
}
Data provider dodává pro tentýž test několik případů. Podle dokumentace PHPUnit musí být veřejný a statický. Počítá se v centech jako celé číslo, aby nevznikaly chyby zaokrouhlení při použití čísel s plovoucí řádovou čárkou. Sada se spouští příkazem ./vendor/bin/phpunit, pokud je PHPUnit nainstalován přes Composer.
Pest: stejný základ, kratší zápis
Pest je podle dokumentace postaven na PHPUnit. Testy se píší jako funkce pomocí it() nebo test() a očekávání pomocí expect(). Pest 5 vyžaduje PHP 8.4. Instalace podle dokumentace:
composer remove phpunit/phpunit
composer require pestphp/pest --dev --with-all-dependencies
./vendor/bin/pest --init
Stejný test v zápisu Pest:
<?php
it('berechnet den Bruttopreis zum Normalsatz', function () {
expect(bruttopreis(10000, 19))->toBe(11900);
});
Stávající testy PHPUnit plugin pestphp/pest-plugin-drift většinou převede automaticky. Jaký zápis tým zvolí, je věc vkusu; rozhodující je, aby testy pravidelně běžely.
Které druhy testů dávají smysl
- Unit testy: ověřují jednotlivé funkce a třídy bez databáze a sítě.
- Integrační testy: ověřují součinnost s databází, souborovým systémem nebo rozhraními.
- Funkční testy přes HTTP: volají stránky a formuláře tak, jak to dělá prohlížeč.
- Bezpečnostní regresní testy: zachycují opravené chyby, například že se výstupy escapují pomocí
htmlspecialchars()nebo že přihlášení po špatném hesle selže. - Smoke testy po nasazení: několik rychlých kontrol, zda živý web po aktualizaci odpovídá.
Jako doplněk k testům hledá statická analýza pomocí PHPStan a Psalm chyby bez spuštění kódu.
Testy jako záchranná síť pro aktualizace a PHP2Shell
PHP2Shell ukázal, jak krátká může být doba mezi zveřejněním a tlakem jednat: oznámení 20. 10. 2026, záplaty 21. 10. 2026, výstražný stupeň BSI oranžový. Kdo měl testovací sadu, mohl PHP 8.4.27 nebo 8.3.36 nasadit v testovacím prostředí, nechat proběhnout testy a ještě týž den jít naostro. Bez testů zůstávala často jen volba mezi neověřenou aktualizací a otevřenou zranitelností.
Ještě větší je přínos při změně hlavní verze. Pro PHP 8.1 a starší už neexistují oficiální aktualizace a PHP 8.2 končí 31. 12. 2026, jak vysvětluje stránka PHP End of Life. Testovací běh proti cílové verzi brzy ukáže, které zastaralé funkce je nutné nahradit. Smysluplná je CI pipeline, která pouští testy proti několika verzím PHP, k tomu pohled na release candidates jako PHP 8.6.0, nikdy však v produkci.
Ke každé opravené bezpečnostní chybě ve vaší aplikaci napište test. Tak zajistíte, že se stejná chyba při pozdější změně nevrátí.
Jak konkrétně pomáhá PHP SOS?
U migrace z PHP 8.1 a starších i při průběžných aktualizacích podporujeme takto:
- Posoudit stav: Jaké testy existují, jaká verze PHP a PHPUnit běží, kde chybí testy pro kritické postupy?
- Vytvořit minimální pokrytí: Společně s vaším vývojovým týmem nebo agenturou zajistíme testy pro přihlášení, formuláře a objednávkové cesty.
- Testovat aktualizace: Nové verze PHP nejprve běží v testovacím prostředí proti sadě testů.
- Zdokumentovat výsledek: Obdržíte výsledky testů a stavy verzí jako doklad pro krok záplatování nebo migrace.
Časté dotazy
Jakou verzi PHPUnit potřebuji?
Záleží na vaší verzi PHP. PHPUnit 13 vyžaduje PHP 8.4, PHPUnit 12 PHP 8.3 a PHPUnit 11 PHP 8.2. Aktuální tabulka je na phpunit.de v přehledu podporovaných verzí.
Je Pest náhradou za PHPUnit?
Pest je podle vlastní dokumentace postaven na PHPUnit a nabízí kratší zápis. Stávající testy PHPUnit lze pomocí pluginu Drift většinou převést automaticky, některé je nutné upravit ručně.
Pomáhají testy proti bezpečnostním zranitelnostem v samotném PHP?
Nikoli přímo. Zranitelnosti jako PHP2Shell sídlí v interpretu a odstraní je aktualizace PHP. Testy ale zajistí, že tuto aktualizaci můžete nasadit rychle, bez obav z nepozorovaných chyb v aplikaci.
Kolik testů stačí?
Pevné číslo neexistuje. Smysluplné je nejprve pokrýt obchodně kritické cesty: přihlášení, objednávku, formuláře, rozhraní. Pokrytí testy pak roste s každou změnou a každou opravenou chybou.