Permalink

0

Alle unterdrückten Fehler in PHPUnit anzeigen

Bei der Entwicklung meiner Libraries kommt es vor, dass eine Änderung nicht mehr abwärtskompatibel ist. Man spricht dann von einem „Backwards Compatability break, kurz „BC break“. Da ich mich aber gerne nach Semver richte, bedeutet ein BC Break, dass die Major-Version der Library hochgesetzt werden.

Nur ist es so, dass ich meinen Nutzern gerne die Möglichkeit gebe, erst auf die neuste Minor-Version zu updaten und dort dann alle Änderungen durchzuführen, die für das Upgrade auf die neue Major-Version nötig sind. Wenn die Änderungen durchgeführt wurden, kann dann das Upgrade auf die neue Version durchgeführt werden, ohne dass es zu BC Breaks kommt.

Wie funktioniert das? Ich halte mich dabei an die Deprecations Conventions von Symfony. Das bedeutet, dass Methoden oder Klassen, die in der nächsten Major-Version nicht mehr verfügbar sind oder anders funktionieren, einen Error triggern.

@trigger_error('XXX() is deprecated since version 2.8 and will be removed in 3.0. Use XXX instead.', E_USER_DEPRECATED);

So sieht das zum Beispiel bei mir aus:

Dabei ist wichtig, dass dem trigger_error() ein @ vorangestellt wird. Auf diese Weise kann der Nutzer auf die neuste Minor-Version updaten, ohne von lauter Deprecated-Errors genervt zu werden. Erst, wenn man sich bewusst um diese Fehler kümmern will, soll man sie sehen können. Aber wie macht man das? Genau darum geht es in diesem Post.

Meine Libraries teste ich in der Regel mit PHPUnit. Wenn ich dort die Tests ausführe, werden die Deprecation-Errors nicht angezeigt, weil sie ja stummgeschaltet sind.

Um diese jetzt doch zu sehen, müssen wir einen eigenen Error-Handler einsetzen, der die Stummschaltung durch das @-Zeichen ignoriert. Ich lege diesen Handler in einer autoload.php im Projektverzeichnis ab.

<?php

require 'vendor/autoload.php';

// Error Handler, der nur stummgeschaltete Errors anzeigt
set_error_handler(function ($errno, $errstr, $errline, $errfile ) {
    if (0 === error_reporting()) {
        throw new \PHPUnit\Framework\Error\Error($errstr, $errno, $errfile, $errline);
    }
});

Diese Datei lasse ich von Git ignorieren, weil ich sie nur für meine Entwicklung benötige. Um den Handler zu aktivieren, brauche ich nur noch in der phpunit.xml die Bootstrap-Datei gegen meine Datei auszutauschen. Dadurch wird der Error Handler aktiviert.

<phpunit bootstrap="autoload.php">

Wenn ich jetzt die Tests ausführen lasse, werden mir auch die unterdrückten Fehler angezeigt und ich kann sehen, woher sie kommen.

Vor dem Release einer einer neuen Major-Version kann ich so alle Deprecated-Errors durchgehen und die veralteten Klassen und Methoden löschen.