PHPUnit 12.5: Neue Notices, Performance-Boost und die klare Trennung von Stubs und Mocks

Von Roland Golla
0 Kommentar
PHPUnit 12.5: Neue Notices, Stubs vs Mocks und Performance-Boost.

Die Welt der PHP-Testautomatisierung hat sich mit der Veröffentlichung von PHPUnit 12.5 wieder einen Schritt weiterentwickelt. In unserer neuesten Never-Code-Alone Session hatten wir das Privileg, mit Sebastian Bergmann, dem Schöpfer von PHPUnit, über die Neuerungen zu sprechen – und die Details sind so praktisch wie inspirierend.

Die zwei großen Highlights in PHPUnit 12.5

1. Die erleuchtende Unterscheidung: Stubs vs. Mocks

Seit Jahren verwenden Entwickler die Begriffe „Stubs“ und „Mocks“ synonym, doch PHPUnit 12.5 bringt endlich Klarheit in diese babylonische Sprachverwirrung:

Test Stubs verwenden wir, um uns von Abhängigkeiten zu entkoppeln, die indirekte Eingabe liefern. Beispiel: Ein Database-Repository, das fest definierte Daten zurückgibt, ohne mit einer echten Datenbank zu sprechen.

Mock Objects benötigen wir dagegen, wenn wir indirekte Ausgabe testen wollen – also die Kommunikation zwischen Objekten. Beispiel: Sicherstellen, dass ein Service nach einer Aktion tatsächlich einen Logger aufruft.

// Bisher: Immer createMock() verwendet
$databaseMock = $this->createMock(Database::class);

// Jetzt in PHPUnit 12.5: Besserer Ansatz
$databaseStub = $this->createStub(Database::class);
$databaseStub->method('query')->willReturn(['data']);

// ODER bei tatsächlich benötigtem Mock:
$loggerMock = $this->createMock(Logger::class);
$loggerMock->expects($this->once())
           ->method('log')
           ->with('error', 'Something went wrong');

Die neue PHPUnit Notice warnt dich nun, wenn du createMock() ohne konfigurierte Erwartungen verwendest – ein sanfter Hinweis, dass du wahrscheinlich nur einen Stub brauchst.

2. Performance-Explosion für Infection

Markus Staab hat signifikante Verbesserungen am Code-Coverage-XML-Format von PHPUnit vorgenommen, was zu einem 40-50% Performance-Boost für Infection (das Mutation-Testing-Tool) führte. Der Trick: Das optionale Weglassen des <source>-Elements im Coverage-Report, das für statische Code-Analyse vorverarbeitete Tokens enthielt – eine Information, die Infection gar nicht benötigt.

Praktische Implikationen für deine Test-Suite

Bessere Test-Lesbarkeit durch klare Intention

Wenn du in deinen Tests konsequent createStub() für Eingabe-Abhängigkeiten und createMock() nur für Ausgabe-Überprüfungen verwendest, wird dein Testcode selbsterklärender. Neue Teammitglieder (oder dein zukünftiges Ich) können schneller erfassen, was ein Test eigentlich prüfen soll.

// Klare Intention: Nur Eingabe steuern
$userRepositoryStub = $this->createStub(UserRepository::class);
$userRepositoryStub->method('findAll')->willReturn([$user1, $user2]);

// Klare Intention: Ausgabe überprüfen
$emailServiceMock = $this->createMock(EmailService::class);
$emailServiceMock->expects($this->exactly(2))
                 ->method('send');

Die neue Notice-Stufe: Dein freundlicher Code-Reviewer

PHPUnit führt eine neue Notice-Stufe ein, die zwischen „risky“ und kompletter Ignoranz liegt. Die erste Notice dieser Art warnt vor unkonfigurierten Mock-Objects. Du kannst sie pro Klasse mit einem Attribut deaktivieren:

#[AllowMockingUnknownTypes]
class MyCustomTestCase extends TestCase
{
    // Dein Test-Code
}

Dieser Ansatz verhindert, dass Teams die Notice global abschalten und so das wertvolle Feedback verlieren.

Wie du dich auf PHPUnit 13 vorbereitest

PHPUnit folgt einem vorhersagbaren Release-Zyklus:

  • Februar jedes Jahres: Major-Release (z.B. PHPUnit 13) mit Breaking Changes
  • Dezember: Feature-Release (z.B. 12.5) als letzte Version einer Serie

Für den Übergang zu PHPUnit 13 solltest du:

  1. Die Deprecation-Warnungen in 12.5 ernst nehmen – sie zeigen dir, was sich in 13.0 ändern wird

  2. Auf typsichere Assertions umsteigen:


    // Deprecated in 12.5, entfernt in 13.0:
    $this->assertIsType('array', $value);

    // Neu und typsicher:
    $this->assertIsArray($value);
    $this->assertIsBool($value);
    $this->assertIsCallable($value);

  3. Tools wie Rector nutzen, um die Migration zu automatisieren

Wie du zu PHPUnit beitragen kannst (auch ohne tiefes Framework-Wissen)

Sebastian betonte im Gespräch mehrere Wege, wie Entwickler zum Projekt beitragen können:

  1. Feedback geben: „Das Feature verstehe ich nicht“ oder „Hier hakt es“ ist extrem wertvoll
  2. Bug-Reports reproduzieren: Selbst wenn du den Fix nicht kennst, hilft Bestätigung
  3. Dokumentation verbessern: Unklare Stellen aufzeigen oder direkt verbessern
  4. Good-First-Isses im Issue-Tracker ansehen

Ein konkreter Einstiegspunkt: Neue Assertions schreiben. Die Struktur in PHPUnit ist konsistent:

  • Jede Assertion hat eine inverse Variante (assertHasKey / assertNotHasKey)
  • Die Logik wird in Constraint-Objekten gekapselt
  • Tests verwenden Data Provider für verschiedene Eingabeszenarien

Die menschliche Seite von Open-Source-Maintenance

Sebastian gab einen ehrlichen Einblick in die Herausforderungen von Open-Source-Maintenance:

  • Jeder akzeptierte Pull Request bedeutet langfristige Verantwortung
  • Feature-Requests direkt mit PRs zu verbinden ist riskant (viel investierte Zeit vs. mögliche Ablehnung)
  • Das größte Geschenk für Maintainer ist konstruktives Feedback

Schulungsangebote und Ressourcen

Für Entwickler, die tiefer einsteigen wollen:

  • Testautomation mit PHPUnit: Einstiegskurs für verlässlichen Code (Januar, 4×2 Stunden)
  • What’s new in PHP 8.5: Update-Schulung zu den neuesten PHP-Features
  • Debugging deep dive: Techniken jenseits von XDebug

Alle Artikel und Ressourcen zum Thema findet ihr auf phpunit.expert – inklusive eines ausführlichen Artikels zu Stubs und Mocks, der die heutige Diskussion vertieft.

Fazit: PHPUnit wird erwachsener – und hilfreicher

PHPUnit 12.5 markiert einen wichtigen Schritt in der Evolution des Frameworks. Es geht nicht mehr nur um reine Funktionalität, sondern um Developer Experience und Code-Qualität durch bessere Feedback-Loops. Die neue Unterscheidung zwischen Stubs und Mocks, kombiniert mit den hilfreichen Notices, macht PHPUnit zu einem noch besseren Lehrer für Test-Driven Development.

Die größte Erkenntnis aus dem Gespräch: 90% der Fälle, in denen du Test Doubles brauchst, sind Stubs – keine Mocks. Wenn du also das nächste Mal createMock() schreibst, frage dich: „Teste ich hier wirklich die Kommunikation zwischen Objekten, oder will ich nur Eingabe steuern?“


Timestamps aus dem Video:

  • 00:00 Begrüßung & Einführung PHPUnit 12.5 mit Sebastian Bergmann
  • 06:45 Die philosophische Frage: Wer contributet zu PHPUnit?
  • 22:10 Kernkonzept erklärt: Test Stubs vs. Mock Objects – der fundamentale Unterschied
  • 41:30 Live-Demo: Neue PHPUnit Notice für unkonfigurierte Mock Objects
  • 58:15 Performance-Story: Wie Markus Staab Infection um 40-50% beschleunigte
  • 1:15:45 Contributing Guide: Vom Issue bis zum ersten Pull Request
  • 1:29:20 Code-Deep Dive: Wie eine PHPUnit Assertion intern funktioniert
  • 1:41:10 Ausblick PHPUnit 13, Deprecations & Schulungsangebote
  • 1:49:00 Verabschiedung

Habt ihr bereits Erfahrung mit den neuen Features von PHPUnit 12.5 gemacht? Teilt eure Gedanken in den Kommentaren!

0 Kommentar

Tutorials und Top Posts

Gib uns Feedback

Diese Seite benutzt Cookies. Ein Akzeptieren hilft uns die Seite zu verbessern. Ok Mehr dazu