Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains und...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte Internetdienstleistungen...
https://www.Artfiles.de
 
 
 

PHP Unit Test Generator

Unit-Tests gehören zum guten Stil moderner PHP-Entwicklung. Sie dokumentieren, was eine Klasse tun soll, warnen dich beim nächsten Refactoring, wenn etwas kaputtgegangen ist, und zwingen dich beim Schreiben dazu, deine Klassen so zu bauen, dass sie überhaupt testbar bleiben. Wer mit PHPUnit noch nicht gearbeitet hat, findet dort einen ausführlichen Einstieg.

Trotzdem ist gerade das Anlegen der ersten Tests oft eine mühsame Schreibarbeit. Eine Testklasse erbt von TestCase, das setUp() muss die Konstruktor-Abhängigkeiten der Klasse vorbereiten, und für jede Methode kommt eine eigene test*-Funktion. Das Tool auf dieser Seite nimmt dir genau diese Boilerplate ab und liefert dir ein einsatzbereites Test-Skelett, in das du nur noch die konkreten Erwartungen eintragen musst.

So benutzt du den Generator: Füge deinen PHP-Quellcode in das Eingabefeld ein, wähle die passenden Optionen (PHPUnit oder Codeception, Mocks ja oder nein, Data-Provider mitgenerieren) und klicke auf Tests generieren. Das Ergebnis kannst du direkt in die Zwischenablage kopieren, als .php-Datei herunterladen oder in einem von bis zu 20 lokalen Projekt-Slots ablegen, um später daran weiterzuarbeiten. Die Slot-Sammlung lässt sich als JSON-Datei exportieren und importieren, sodass du sie zwischen Browsern oder Rechnern mitnehmen kannst.

Glossar: Fachbegriffe kurz erklärt
SUT (System Under Test)
Die Klasse, die gerade getestet wird. Im generierten Code heißt die Variable $this->sut (mit Konstruktor-Abhängigkeiten) oder $sut (ohne Abhängigkeiten).
Mock
Eine Test-Attrappe einer echten Klasse. Verhält sich vorhersagbar, statt echte Aufrufe an Datenbank, Filesystem oder API zu machen. PHPUnit erzeugt Mocks mit $this->createMock(Klasse::class).
Stub
Vereinfachter Mock, der nur vordefinierte Rückgabewerte liefert, ohne die Aufrufe selbst zu prüfen. In PHPUnit technisch über denselben Mock-Builder umgesetzt.
Assertion
Eine Prüfung, die der Test über das Ergebnis aufstellt. Beispiel: assertSame(5, $result) schlägt fehl, wenn $result nicht exakt der Integer 5 ist.
Data Provider
Eine statische Methode, die mehrere Eingabe-Sätze für denselben Test liefert. So prüfst du dieselbe Logik mit verschiedenen Werten, ohne die Testmethode zu duplizieren.
Arrange / Act / Assert (AAA)
Test-Aufbau in drei Phasen: Arrange bereitet Daten und Abhängigkeiten vor, Act ruft die zu testende Methode auf, Assert prüft das Ergebnis. Der Generator setzt diese Kommentare automatisch.
Test-Stub / Test-Skelett
Der vom Generator erzeugte Grundgerüst-Test mit // TODO-Markern. Erspart dir Boilerplate, du ergänzt nur noch die konkreten Erwartungen.
Coverage / #[CoversClass]
PHPUnit kann zählen, welche Klasse durch welchen Test abgedeckt wird. Das PHP-Attribut #[CoversClass(...)] (PHPUnit 10+) oder der PHPDoc-Tag @covers (PHPUnit 9) erklärt PHPUnit explizit, welche Klasse dieser Test prüfen soll. Pest nutzt dafür die globale Funktion covers(Klasse::class).

Eingabe

Tipp: Beispielklasse mit dem Button "Beispiel laden" einfügen. Mit Strg+Enter (bzw. Cmd+Enter) im Eingabefeld direkt Tests generieren.

Optionen

Tipp: Bewege die Maus über eine Option, um eine kurze Erklärung zu sehen.

Projekt-Slots

Speichere mehrere Klassen-/Test-Paare lokal im Browser. Es werden bis zu 20 Slots unterstützt. Mit Export sicherst du alle Slots als JSON-Datei, mit Import liest du sie auf einem anderen Rechner oder in einem anderen Browser wieder ein.

Generierte Tests

Was der Generator aus deinem Code herausliest

Der Generator läuft komplett im Browser, dein Code geht an keinen Server. Es kommt kein vollwertiger PHP-Parser zum Einsatz, sondern ein abgespeckter Token-Scanner. Der deckt die typischen Strukturen moderner PHP-Klassen zuverlässig ab:

  • Namespace und Klassenname, auch in den Varianten final class, abstract class sowie readonly class (auch in Kombinationen wie final readonly class). Genauso werden Enums erkannt, sowohl die einfache Form enum Status als auch Backed Enums wie enum Status: string. Methoden auf Enums werden über die erste gefundene case als $sut = EnumName::FirstCase; getestet.
  • Konstruktor inklusive Constructor Promotion. Aus public function __construct(private UserRepository $users) erkennt der Scanner, dass UserRepository eine Abhängigkeit der Klasse ist, und richtet dafür im setUp() automatisch einen Mock ein.
  • Methodensignaturen mit Sichtbarkeit (public, protected, private) und static-Modifier. Statische Methoden werden anschließend korrekt über Klasse::methode() aufgerufen, nicht über eine Instanz. Bei static in Kombination mit Reflection erhält $ref->invoke() als erstes Argument null statt der SUT.
  • Parameter und Return-Type-Hints, inklusive nullable Varianten (?int, ?array), Union-Types und Variadic-Parameter (string ...$tags). Variadic-Argumente werden im Test-Aufruf mit zwei Beispielwerten gespiegelt, damit klar wird, dass die Methode mehrere Werte annehmen kann.
  • Skalare Default-Werte, die direkt in die Beispiel-Aufrufe der generierten Tests einfließen
  • PHPDoc-@throws oberhalb einer Methode. Der erste gefundene Exception-Typ wird in $this->expectException(...) umgesetzt, die Rückgabe-Zuweisung entfällt und der Standard-Assert-Block wird unterdrückt. Weitere @throws-Einträge werden als Kommentar angehängt, weil expectException() sich nicht stapeln lässt und jeder weitere Aufruf den vorherigen überschreiben würde.

Findet der Scanner mehrere Klassen oder Enums in derselben Datei, wählt er den ersten Typ aus und meldet das als Hinweis. interface und trait erkennt der Scanner nicht als Test-Ziel und gibt eine entsprechende Fehlermeldung aus, statt veralteten Output stehenzulassen. Property Hooks (PHP 8.4) im Klassenrumpf stören den Scanner nicht, werden aber auch nicht eigens getestet, weil sie sich semantisch eher über den Zustand der Property als über Methodenaufrufe prüfen lassen. An seine Grenze kommt der Scanner außerdem bei generischen Templates über PHPDoc oder bei sehr ungewöhnlichen Whitespace-Konstellationen. Für diese Fälle lohnt sich ein kurzer Blick auf den Output, bevor du ihn ins Projekt übernimmst. Wie der Generator aus dieser Erkennung dann den fertigen Test baut, regelt ein festes Style-Schema.

So sieht der generierte Code aus

Der erzeugte Test ist PSR-12-konform. declare(strict_types=1); steht als erste Anweisung in der Datei, die Klassenklammer landet auf einer eigenen Zeile, ein abschließendes ?>-Tag wird weggelassen, und jede Testmethode bekommt : void als Return-Type.

Als Default-Assertion benutzt der Generator durchgehend assertSame(). Der Vorteil gegenüber assertEquals(): assertSame() vergleicht auch den Datentyp und nicht nur den Wert. Eine Methode, die statt einer 0 versehentlich den String "0" zurückgibt, fällt damit sofort auf. Die assertIsInt()/assertIsString()-Familie meidet der Generator bewusst, weil sie nur den Typ prüft, nicht den konkreten Wert.

Je nach Return-Type setzt der Generator passende Default-Erwartungen:

  • int, floatassertSame(0 /* TODO */, $result)
  • stringassertSame('' /* TODO */, $result)
  • array, iterableassertSame([] /* TODO */, $result)
  • boolassertTrue($result) mit Hinweis auf assertFalse als Alternative
  • void, neverexpectNotToPerformAssertions()
  • Objekt-Rückgaben oder unbekannte Typen → assertSame(null /* TODO */, $result) als Fallback

Die // TODO: erwartet-Marker zeigen dir, wo du die konkrete Erwartung eintragen musst.

Wirft die Methode laut PHPDoc-@throws-Tag eine Exception, ändert sich der Aufbau: statt einer Assertion auf den Rückgabewert setzt der Generator ein $this->expectException(...) vor dem Aufruf, wobei die Klasse aus dem @throws-Tag übernommen wird. Stehen mehrere @throws über der Methode, gewinnt der erste Eintrag — expectException() lässt sich in PHPUnit nicht stapeln, jeder weitere Aufruf würde den vorherigen überschreiben. Die zusätzlichen Exception-Klassen tauchen als Kommentar im Test auf, damit du sie für eigene Testmethoden sofort siehst. Die // Act-Zeile ruft die Methode dann ohne $result = auf, weil eine geworfene Exception die Zuweisung unterbricht und PHPUnit selbst prüft, ob der Erwartungswert eingetreten ist.

Sind im Konstruktor Abhängigkeiten vom Typ einer Klasse oder eines Interfaces definiert und ist die Option Mocks aktiviert, erzeugt der Generator zusätzlich ein vorgefertigtes setUp() mit $this->createMock()-Aufrufen und einer fertig zusammengebauten $sut-Property (System under Test). Damit bist du in jeder Testmethode sofort startbereit. Für das Testen von private- und protected-Methoden setzt der Generator auf ReflectionMethod, sobald du die entsprechende Option aktivierst. So kannst du auch interne Hilfsmethoden testen, ohne sie für den reinen Testzweck auf public hochzustufen.

Beispiel: Eingabe und Ausgabe gegenübergestellt

Damit klarer wird, was das Tool eigentlich tut, hier ein Vorher-Nachher mit etwas mehr Fleisch am Knochen. Aus dieser readonly class mit einer Konstruktor-Abhängigkeit, einem Variadic-Parameter und einem dokumentierten @throws:

<?php

namespace App\Service;

use App\Repository\UserRepository;

final readonly class Notifier
{
    public function __construct(private UserRepository $users) {}

    /**
     * @throws \RuntimeException when sending fails
     */
    public function notify(int $userId, string ...$tags): bool
    {
        return $this->users->mark($userId, $tags);
    }
}

generiert der Generator mit aktivierten Mocks folgendes Test-Skelett. Achte auf drei Details: die readonly-Variante wird sauber erkannt, der Variadic-Parameter erscheint als zwei Beispiel-Werte im Aufruf, und der @throws-Block aus dem PHPDoc verwandelt sich in einen eigenen // Expect-Abschnitt mit expectException(). Die // Act-Zeile läuft folgerichtig ohne $result =:

<?php

declare(strict_types=1);

namespace Tests\Service;

use App\Service\Notifier;
use PHPUnit\Framework\TestCase;

#[\PHPUnit\Framework\Attributes\CoversClass(Notifier::class)]
final class NotifierTest extends TestCase
{
    /** @var \PHPUnit\Framework\MockObject\MockObject&UserRepository */
    private $users;
    private Notifier $sut;

    protected function setUp(): void
    {
        parent::setUp();
        $this->users = $this->createMock(UserRepository::class);
        $this->sut = new Notifier($this->users);
    }

    public function testNotify(): void
    {
        // Arrange

        // Expect
        $this->expectException(\RuntimeException::class);

        // Act
        $this->sut->notify(0, '', '' /* variadic */);
    }
}

An solchen Stellen merkst du, wieviel Tipparbeit dir der Generator abnimmt. Wer noch tiefer in das Thema einsteigen will, findet im PHPUnit-Tutorial die Erklärung der einzelnen Assertions, im Tutorial zu PSR-4-Autoloading die passende Verzeichnisstruktur für dein Test-Setup und im Composer-Tutorial eine Anleitung, wie du PHPUnit als Dev-Dependency in dein Projekt aufnimmst.

 
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.