Kurz gesagt: PHPUnit ist das Standardwerkzeug, um PHP-Code automatisch zu testen; Pest ist ein darauf aufbauendes Framework mit kürzerer Schreibweise. Aktuell ist PHPUnit 13 (seit Februar 2026, ab PHP 8.4), Pest liegt in Version 5 vor. Automatische Tests schließen keine Sicherheitslücken in PHP selbst, aber sie machen Updates planbar: Nach PHP2Shell und vor dem Supportende von PHP 8.2 am 31.12.2026 ist das der entscheidende Vorteil.
Warum PHP-Code testen?
Für die Geschäftsführung lässt sich der Nutzen in einem Satz fassen: Tests machen Änderungen billiger und sicherer. Ein automatischer Test prüft in Sekunden, ob eine Funktion noch das tut, was sie soll, etwa ob ein Warenkorb richtig rechnet oder ein Login falsche Passwörter ablehnt. Ohne Tests prüft das ein Mensch von Hand, oder niemand.
Besonders deutlich wird der Unterschied bei Updates. Muss PHP wegen einer kritischen Lücke kurzfristig aktualisiert werden, zögern viele Betreiber, weil sie Fehler im Shop oder im Kundenportal fürchten. Mit einer Testsuite läuft das Update erst in einer Testumgebung, die Tests zeigen Probleme, und danach geht es live.
PHPUnit: der Standard für PHP-Tests
PHPUnit erscheint jedes Jahr im Februar in einer neuen Hauptversion. Jede Version setzt eine Mindestversion von PHP voraus und erhält rund zwei Jahre Fehlerkorrekturen. Laut phpunit.de gilt:
| PHPUnit | Erschienen | PHP-Voraussetzung | Fehlerkorrekturen bis |
|---|---|---|---|
| 13 | 06.02.2026 | ab PHP 8.4 | 04.02.2028 |
| 12 | 07.02.2025 | ab PHP 8.3 | 05.02.2027 |
| 11 | 02.02.2024 | ab PHP 8.2 | 06.02.2026 |
| 10 | 03.02.2023 | ab PHP 8.1 | 07.02.2025 |
Die Tabelle zeigt einen praktischen Zusammenhang: Ein Projekt, das noch PHPUnit 10 nutzt, läuft meist auch noch auf einer alten PHP-Version. Testwerkzeuge und PHP-Version sollten gemeinsam angehoben werden. Installiert wird PHPUnit üblicherweise über Composer als Entwicklungsabhängigkeit.
Ein erster Test mit PHPUnit
Ein Test ist eine Klasse, die von PHPUnit\Framework\TestCase erbt. Testmethoden sind öffentlich und beginnen mit test, alternativ markiert man sie mit dem Attribut #[Test]. Das Beispiel prüft eine einfache Funktion zur Preisberechnung:
<?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));
}
}
Der Data Provider liefert mehrere Fälle für denselben Test. Er muss laut PHPUnit-Dokumentation öffentlich und statisch sein. Gerechnet wird in Cent als Ganzzahl, damit keine Rundungsfehler durch Gleitkommazahlen entstehen. Ausgeführt wird die Suite mit ./vendor/bin/phpunit, wenn PHPUnit über Composer installiert ist.
Pest: dieselbe Basis, kürzere Schreibweise
Pest ist laut Dokumentation auf PHPUnit aufgebaut. Tests werden als Funktionen mit it() oder test() und Erwartungen mit expect() geschrieben. Pest 5 setzt PHP 8.4 voraus. Die Installation laut Dokumentation:
composer remove phpunit/phpunit
composer require pestphp/pest --dev --with-all-dependencies
./vendor/bin/pest --init
Derselbe Test in Pest-Schreibweise:
<?php
it('berechnet den Bruttopreis zum Normalsatz', function () {
expect(bruttopreis(10000, 19))->toBe(11900);
});
Bestehende PHPUnit-Tests wandelt das Plugin pestphp/pest-plugin-drift größtenteils automatisch um. Welche Schreibweise ein Team wählt, ist Geschmackssache; entscheidend ist, dass Tests regelmäßig laufen.
Welche Testarten sinnvoll sind
- Unit-Tests: prüfen einzelne Funktionen und Klassen ohne Datenbank oder Netzwerk.
- Integrationstests: prüfen das Zusammenspiel mit Datenbank, Dateisystem oder Schnittstellen.
- Funktionstests über HTTP: rufen Seiten und Formulare auf, wie es ein Browser tut.
- Sicherheits-Regressionstests: halten behobene Fehler fest, etwa dass Ausgaben mit
htmlspecialchars()maskiert werden oder ein Login nach falschem Passwort scheitert. - Smoke-Tests nach dem Deployment: wenige schnelle Prüfungen, ob die Live-Seite nach einem Update antwortet.
Ergänzend zu Tests findet die statische Analyse mit PHPStan und Psalm Fehler, ohne den Code auszuführen.
Tests als Sicherheitsnetz für Updates und PHP2Shell
PHP2Shell hat gezeigt, wie kurz die Zeit zwischen Veröffentlichung und Handlungsdruck sein kann: Ankündigung am 20.10.2026, Patches am 21.10.2026, BSI-Warnstufe Orange. Wer eine Testsuite hatte, konnte PHP 8.4.27 oder 8.3.36 in einer Testumgebung einspielen, die Tests laufen lassen und am selben Tag live gehen. Ohne Tests blieb oft nur die Wahl zwischen ungeprüftem Update und offener Lücke.
Noch größer ist der Nutzen beim Wechsel der Hauptversion. Für PHP 8.1 und älter gibt es keine offiziellen Updates mehr, und PHP 8.2 endet am 31.12.2026, wie die Seite PHP-End-of-Life erklärt. Ein Testlauf gegen die Zielversion zeigt früh, welche veralteten Funktionen ersetzt werden müssen. Sinnvoll ist eine CI-Pipeline, die Tests gegen mehrere PHP-Versionen fährt, dazu ein Blick auf Release Candidates wie PHP 8.6.0, allerdings nie in der Produktion.
Schreiben Sie zu jedem behobenen Sicherheitsfehler in Ihrer Anwendung einen Test. So stellen Sie sicher, dass derselbe Fehler bei einer späteren Änderung nicht zurückkehrt.
Wie hilft PHP SOS konkret?
Bei der Migration von PHP 8.1 und älter und bei laufenden Updates unterstützen wir so:
- Bestand bewerten: Welche Tests gibt es, welche PHP- und PHPUnit-Version laufen, wo fehlen Tests für kritische Abläufe?
- Mindestabdeckung schaffen: Gemeinsam mit Ihrem Entwicklungsteam oder Ihrer Agentur sichern wir Login, Formulare und Bestellwege mit Tests ab.
- Updates testen: Neue PHP-Versionen laufen zuerst in einer Testumgebung gegen die Suite.
- Ergebnis dokumentieren: Sie erhalten Testergebnisse und Versionsstände als Nachweis für den Patch- oder Migrationsschritt.
Häufige Fragen
Welche PHPUnit-Version brauche ich?
Das hängt von Ihrer PHP-Version ab. PHPUnit 13 setzt PHP 8.4 voraus, PHPUnit 12 PHP 8.3 und PHPUnit 11 PHP 8.2. Die aktuelle Tabelle steht auf phpunit.de unter den unterstützten Versionen.
Ist Pest ein Ersatz für PHPUnit?
Pest ist laut eigener Dokumentation auf PHPUnit aufgebaut und bietet eine kürzere Schreibweise. Bestehende PHPUnit-Tests lassen sich mit dem Drift-Plugin größtenteils automatisch umwandeln, einige müssen von Hand angepasst werden.
Helfen Tests gegen Sicherheitslücken in PHP selbst?
Nicht direkt. Lücken wie PHP2Shell stecken im Interpreter und werden durch ein PHP-Update geschlossen. Tests sorgen aber dafür, dass Sie dieses Update schnell einspielen können, ohne Angst vor unbemerkten Fehlern in der Anwendung.
Wie viele Tests sind genug?
Eine feste Zahl gibt es nicht. Sinnvoll ist, zuerst die geschäftskritischen Wege abzudecken: Anmeldung, Bestellung, Formulare, Schnittstellen. Danach wächst die Testabdeckung mit jeder Änderung und jedem behobenen Fehler.