Aktuální situace: PHP2Shell. Dvě kritické zranitelnosti PHP (CVSS 9.2) umožňují spustit škodlivý kód bez přihlášení. Záplaty od 21. 10. 2026.Co nyní udělat →

Testování kódu PHP: PHPUnit a Pest

PHPUnit je standardní testovací nástroj pro PHP, Pest na něm staví. Kdo má testy, může nasazovat bezpečnostní aktualizace a změny verzí rychleji a s menším rizikem.

Stav 4 min čteníZnalosti o PHP

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

  1. Unit testy: ověřují jednotlivé funkce a třídy bez databáze a sítě.
  2. Integrační testy: ověřují součinnost s databází, souborovým systémem nebo rozhraními.
  3. Funkční testy přes HTTP: volají stránky a formuláře tak, jak to dělá prohlížeč.
  4. 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.
  5. 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.

Tip

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.

Zdroje

Okamžitý kontakt

Každá hodina se počítá. Napište nám hned.

Stručně popište systém, verzi PHP a pozorování. Ozveme se, vyjasníme situaci a budeme pracovat na dálku, dokud nebude incident uzavřen a zdokumentován.

Okamžitá pomoc