Interview mit Sebastian Bergmann über die Probleme nach dem Release von PHPUnit 6

PHPUnit 6, Failed Tests und viele Antworten
Kommentare

Sebastian Bergmann hat PHPUnit 6 veröffentlicht. Kurz darauf war es, als würden „Millionen von Tests aufschreien und für immer verstummen“. Nanu?

Freitag, der 03. Februar 2017, war zunächst ein guter Tag: PHPUnit 6.0.0 ist erschienen. An Bord waren zahlreiche neue Features; auf der Strecke geblieben ist der Support von PHP 5. Es schien, als stünden alle Zeichen uneingeschränkt auf Zukunft.

Doch dann passierte etwas Eigenartiges.

Millions of tests suddenly cried out

Innerhalb kürzester Zeit gab es via Twitter zahlreiche Beschwerden über failende Tests. Symfony-Applikationen wollten nicht mehr, Travis zeigte die rote Flagge. Was war geschehen?

Wer die Signale aus den sozialen Netzwerken beobachtete, konnte sich nur wundern. Denn neben enttäuschter User tummelten sich auch viele, die das neue Release und dessen Performance-Gewinn feierten.

PHPUnit 6 – das Interview

Um nun der Sache auf den Grund zu gehen, haben wir mit Sebastian Bergmann über die Situation gesprochen. Und wie sich herausstellte, waren die „Probleme“ vielschichtiger als gedacht. Offensichtlich sind selbst lang vor dem Release veröffentlichte Ankündigungen manchmal nicht genug, um Konfusion zu vermeiden. Aber lest selbst.


Sebastian, nach dem Release von PHPUnit 6 gab es auf Twitter schnell vereinzelte Beschwerden über Probleme mit den Tests; viele Dinge schienen aber auf unterschiedlichen Ebenen zu passieren. Welche Ebenen waren das – was genau ist passiert?

Sebastian Bergmann: Puh. Da ist ganz viel auf einmal passiert.

PHPUnit 6.0 unterstützt nur PHP 7.0 und PHP 7.1, funktioniert also nicht mehr mit PHP 5. Versucht man, PHPUnit 6.0 mit PHP 5 auszuführen, dann bekommt man natürlich einen Fehler.

Die neue Major-Version setzt einen von der PHP-Community lange gehegten Wunsch um, nämlich, dass der Code von PHPUnit Namespaces benutzt. PHPUnit_Framework_TestCase gibt es nicht mehr, Testklassen müssen nun von PHPUnit\Framework\TestCase erben.

Tests, die zwar meiner Meinung nach wertlos und damit riskant sind, von PHPUnit 5.7 aber standardmäßig nicht kritisiert wurden, werden nun also standardmäßig anders interpretiert.

In PHPUnit 6.0 ändern sich darüber hinaus zwei Standardeinstellungen, was bei mancher Testsuite da draußen zu Problemen geführt hat. Zum einen meckert PHPUnit nun standardmäßig Tests an, die nichts testen – also keine Assertion aufrufen, nicht mit expectException() oder @expectedException eine Ausnahme erwarten oder Erwartungen auf einem Mock-Objekt konfigurieren. Tests, die zwar meiner Meinung nach wertlos und damit riskant sind, von PHPUnit 5.7 aber standardmäßig nicht kritisiert wurden, werden nun also standardmäßig anders interpretiert.

Zum anderen erstellt PHPUnit nicht mehr vor jedem Test ein Backup aller globalen und super-globalen Variablen und stellt diese nach jedem Test auch nicht wieder her. Tests für Code, der globale und super-globale Variablen manipuliert, können nun in der Standardkonfiguration fehlschlagen.

Ich glaube, dass es an der Zeit ist, dass Entwickler, die modernen, sauberen, objekt-orientierten Code schreiben, der nicht vom globalen Systemzustand abhängt, in der Standardkonfiguration von PHPUnit nicht mehr den Preis zahlen dafür zahlen müssen, dass alter Code in der Standardkonfiguration über den Mechanismus des Global State-Backups testbar(er) gemacht wird. Das Sichern und Wiederherstellen der globalen und super-globalen Variablen kostet nämlich Speicher und Zeit.

Zu guter Letzt fiel das Release von PHPUnit 6.0 in eine Woche, in der die Entwicklung von PHP 7.2, das ja im Dezember 2017 zu erwarten ist, deutlich an Fahrt aufgenommen hat.

Viele Punkte, mit denen man sich nach und nach beschäftigen sollte … zunächst einmal: Du bist bereits lange im Vorfeld des Release auf die kommenden Änderungen eingegangen – unter anderem auf die Änderung der Klassen in Namespaces. Leider scheint das nicht überall durchgedrungen zu sein. Welche Lehren ziehst du für die Zukunft daraus?

Sebastian: Offensichtlich sind Ankündigungen wie bspw. Preparing for PHPUnit 6 nicht angekommen. Auch scheint es kaum jemanden zu geben, der Nightly Builds von PHAR oder den master-Branch über Composer testet.

Meine Lehre ist also, dass das, was ich bislang gemacht habe, nicht ausreicht. Ich würde mich über Vorschläge freuen, was ich in Zukunft anders oder besser machen könnte.

Viele Nutzer scheinen darüber hinaus immer die aktuellste Version zu ziehen; ohne sich der Änderungen bewusst zu sein.

Sebastian: Ah, der Todesstern, wie ich ihn mittlerweile nenne. Wäre ich jemand, der zu Schadenfreude neigt, dann würde ich jetzt sagen: „Freut mich, dass nicht nur meine Botschaften nicht bei meinen Benutzern ankommen.“

Jordi Boggiano, der Maintainer von Composer, sowie andere, die auf Konferenzen Vorträge über Dependency Management halten, erzählen den Leuten seit Jahren, dass * kein Version Constraint ist.

Das Update auf eine neue Major-Version sollte eine bewusste Aktion sein. Dazu gehört auch das Lesen der Liste von Änderungen.

Ich bin zwar nicht schadenfroh, aber an der Stelle kann ich nicht anders, als zu sagen: Entschuldigung, aber wenn ich "phpunit/phpunit": "*" in meine composer.json-Datei schreibe, dann habe ich das Recht verwirkt, mich darüber zu beschweren, dass eine neue Major-Version von PHPUnit „die Tests kaputt macht“.

Aber im Ernst: PHPUnit verwendet Semantic Versioning. Und eben, weil bestehende Tests für PHPUnit 6 angepasst werden müssen, wurde die Major-Version von 5 auf 6 erhöht. Meine Erwartung als Entwickler eines Werkzeugs wie PHPUnit ist es, dass eine neue Major-Version nicht „einfach so“ installiert wird, sondern dass dies eine bewusste Aktion ist. Hierzu gehört natürlich das Lesen der Liste von Änderungen.

Ein Sonderfall ist der „Problemfall“ Symfony in Kombination mit PHPUnit. Was wurde hier unternommen?

Sebastian: Die Entwickler von Symfony wollen, dass die aktuelle Version – Symfony 3 –kompatibel mit PHP 5.5 ist. Die Testsuite von Symfony 3 muss also (auch) mit PHP 5.5 ausgeführt werden. PHPUnit 4.8 war die letzte Version, die PHP 5.5 unterstützt hat. Jetzt hat aber PHP 5.5 zum einen am 21. Juli 2016, und PHPUnit 4.8 zum anderen am 03. Februar 2017 das End-of-Life erreicht.

Um den Symfony-Entwicklern zu helfen, habe ich diese Woche ein letztes Release von PHPUnit 4.8 veröffentlicht, das nun ebenfalls den Forward Compatibility Layer enthält, den PHPUnit 5 schon eine ganze Weile hatte. Somit weiß nun auch PHPUnit 4.8 mit PHPUnit\Framework\TestCase anstelle von PHPUnit_Framework_TestCase umzugehen. Das hilft den Symfony-Entwicklern, ihre Tests mit PHPUnit 4.8, PHPUnit 5.7 und PHPUnit 6.0 ausführen zu können.

Hinzu kam ein weiteres Problem: PHPUnit 6 war nicht mit PHP 7.0.0 bis 7.0.12 kompatibel – was ist da genau passiert?

Sebastian: *seufz* Das war ein Bug, der mich so verwirrt hat, wie schon lange keiner mehr …

Ein Bug, der mich so verwirrt hat, wie schon lange keiner mehr …

Die Klassen von PHPUnit habe ich für die neue Version mit PhpStorm jeweils in einen Namespace verschoben und danach umbenannt. Das hat bis auf zwei Ausnahmen problemlos funktioniert (und ohne die automatisierten Refactorings von PhpStorm wäre ich verrückt geworden). Da ich sowohl lokal als auch auf Travis nur mit aktuellen stabilen PHP-Versionen – PHP 7.0.15 und PHP 7.1.1 um genau zu sein – getestet habe, sind mir fehlerhaften Umbenennungen nicht aufgefallen. Daher konnte ich einige der Bug-Reports, die nach dem Release kamen, zunächst auch weder reproduzieren noch verstehen.

Erst als ich Travis so konfigurierte, dass die Testsuite von PHPUnit mit allen Releases von PHP 7 (7.0.0, 7.0.1, …, 7.1.0, 7.1.1) ausgeführt wurde, sah ich, dass PHPUnit 6.0 nicht mit PHP 7.0.0 bis 7.0.12 kompatibel war. Einen Chat mit Core-Entwickler Nikita Popov später wusste ich dann, was sich in PHP 7.0.13 geändert hatte. Die Fehler, die das automatisierte Refactoring in Richtung Namespaces gemacht hatte, sind seit PHP 7.0.13 keine Fehler mehr, da PHP das so genannte Namespace Shadowing nun korrekt implementiert. Die Fehler in PHPUnit 6.0 habe ich dann natürlich dennoch behoben, damit die neue Version auch mit älteren PHP-7-Versionen als 7.0.13 verwendet werden kann.

A practical Introduction to Kubernetes

mit Robert Lemke (Flownative GmbH)

PHP 7: Reality Check

mit Sebastian Bergmann (thePHP.cc)

… und dann war da noch die eigentlich amüsante Geschichte mit dem Performance-Boost …

PHPUnit 6 ist nicht schneller als PHPUnit 5. Es ist alles eine Frage der Konfiguration.

Sebastian: Oh, ja. Auf Twitter finden sich viele Tweets, in denen man sich darüber freut, dass die eigene Testsuite mit PHPUnit 6 deutlich schneller ausgeführt wird als mit PHPUnit 5. Diese Freude freut mich natürlich.

Allerdings ist PHPUnit 6 nicht schneller als PHPUnit 5. Dieser Performance-Boost ist einzig und allein in der oben genannten Änderung begründet, dass PHPUnit das Sichern und Wiederherstellen der globalen und super-globalen Variablen nicht mehr standardmäßig durchführt.

Das heißt natürlich, dass man denselben Performance-Boost schon lange hätte haben können, wenn man das entsprechende Feature in seiner PHPUnit-Konfiguration ausgeschaltet hätte.

Du schlägst mit PHPUnit einen gefühlt harten Weg ein: Der Support für PHP 5 ist ausgelaufen, also konzentrierst du dich nur noch auf die unterstützten Versionen. Ist die Realität – also die Verbreitung von PHP 7 in der Praxis – schon bereit dafür?

Sebastian: Von PHPUnit wird erwartet, dass es mit aktuellen PHP-Versionen funktioniert. Das ist okay. Was ich weder für sinnvoll erachte noch zu leisten vermag, ist Kompatibilität aktueller PHPUnit-Versionen mit veralteten PHP-Versionen. Wer heute noch PHP 5.6 (oder eine noch ältere Version) einsetzt, der hat meiner Meinung nach ganz andere Probleme, als dass die aktuelle PHPUnit-Version mit seinen Tests nicht funktioniert. Zum Ende des aktiven Supports von PHP 5.6 habe ich dieses Problem ausführlich in meinem Artikel PHP 5: Active Support Ends. Now what? diskutiert.

Nur weil es eine neue Version von PHPUnit gibt, heißt das nicht, dass die alte aufhört zu funktionieren.

Ich interpretiere Statistiken wie die von Jordi (PHP Version Stats – 2016.Edition) oder Umfragen wie die von euch so, dass zumindest neue Projekte mit PHP 7 umgesetzt werden. Das deckt sich auch mit meiner Erfahrung aus dem Alltag als Berater.

Und was existierende Projekte betrifft, die alte PHPUnit-Versionen verwenden: nur weil es eine neue Version von PHPUnit gibt, heißt das ja nicht, dass die alte aufhört zu funktionieren. Ich bekomme halt keine neuen Features mehr. Und wenn ich einen Bug finde, dann „darf ich den behalten“.

Welche PHP-Version nutzt ihr für eure Applikationen?

View Results

Loading ... Loading ...

Aus der Sicht eines Entwicklers, der viel Wert auf Code-Qualität legt: Hat dich der „Aufschrei“ in der Community nicht auch ein wenig beruhigt? Immerhin scheint ein Tool wie PHPUnit mittlerweile zum Standardrepertoire von PHP-Entwicklern zu gehören …

Sebastian: Die konkreten Probleme der Benutzer von PHPUnit beruhigen mich natürlich nicht. Aber abstrakt gesehen hast Du, glaube ich, Recht. Ja, es ist beruhigend, dass mittlerweile so viele Entwickler PHPUnit aus ihrem Alltag nicht wegdenken können, dass es auffällt, wenn es zu Problemen mit PHPUnit kommt.

Du hast ziemlich schnell ziemlich viele Updates nachgeschoben – vor allem mit PHP 7.2 kam es wegen deprecated Features zu einigen Fehlern. Was werden die nächsten großen Meilensteine sein, die du angehen wirst?

Sebastian: Es war mir ein Bedürfnis, so schnell wie möglich auf die gemeldeten Probleme zu reagieren, auch und gerade mit Bugfix-Releases. Im Prinzip habe ich von Freitagmorgen (03. Februar 2017) bis Sonntagabend nichts Anderes gemacht, als die gemeldeten Probleme zu reproduzieren, zu analysieren und zu beheben. Sobald ein Problem gelöst war, gab es ein Release.

Ich glaube, dass es trotz aller Sorgfalt, die ich bei der Entwicklung sowie beim Release von PHPUnit 6.0 habe walten lassen, noch das eine oder andere Bugfix-Release brauchen wird, bis PHPUnit 6 stabil ist. Spätestens zum Release von PHPUnit 6.1 am 07. April 2017 sollte sich aber alles zurecht gerüttelt haben.

Die Planung für PHPUnit 7.0, das am 02. Februar 2018 erscheinen wird, hat schon begonnen. Unter anderem wird diese Version PHP 7.0 nicht mehr unterstützen, dessen aktiver Support ja im Dezember 2017 enden wird.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -