© Ozz Design/Shutterstock.com
PHP-Code effizienter testen

Mock the Unmockable


Die Codequalität bekommt einen immer größeren Wert in der PHP-Community zugesprochen. So findet man beispielsweise nur noch selten ungetestete Libraries auf GitHub. Zwei Problemstellungen, auf die Entwickler beim Testen jedoch immer wieder stoßen, sind der Umgang mit Dateioperationen und das Testen von Built-in-PHP-Funktionen wie time() oder exec() auf bestimmte Erwartungen. In diesem Artikel möchte ich für solche Fälle Lösungen aufzeigen.

Als PHP-Entwickler kommt man naturgemäß schnell in die Situation, mit Dateien zu arbeiten bzw. zu interagieren, beispielsweise bei der Verarbeitung von hochgeladenen Dateien oder dem Schreiben von Cache- oder Logfiles. Und als guter Entwickler möchte man natürlich auch diesen Programmablauf mit Tests abdecken.

Listing 1 zeigt dabei ein vereinfachtes Beispiel einer CacheWarmer-Klasse, die in der warmUp-Methode ein Cache-Directory anlegt, sollte es nicht bereits existieren.

Listing 1

<?php namespace My\App; class CacheWarmer { private $cacheDirectory; public function __construct(string $cacheDirectory) { $this->cacheDirectory = $cacheDirectory; } public function warmUp() { if (!is_dir($this->cacheDirectory) &&!mkdir($this->cacheDirectory)) { throw new \RuntimeException('Could not create cache directory!'); }  // ... } }

Möchte man so eine Klasse mithilfe eines Unit-Tests testen, wäre die einfachste Herangehensweise, das direkt im Filesystem zu tun. Dabei wird die Klasse lokal initialisiert, die warmUp-Methode aufgerufen und am Ende geprüft, ob das entsprechende Verzeichnis angelegt und gegebenenfalls richtig befüllt wurde. Diese Methode ist zwar schnell und überaus effektiv, beinhaltet jedoch diverse mögliche Probleme. Wird beispielsweise mit einem anderen Betriebssystem als auf dem eigentlichen Zielsystem gearbeitet, müssen die Tests dies entsprechend beachten. Des Weiteren sollte darauf geachtet werden, dass die Tests das Dateisystem im Nachgang auch wieder korrekt bereinigen – zum einen, um Seiteneffekte in abhängigen Tests zu vermeiden, und zum anderen, um zu verhindern, dass das eigene Dateisystem mit Testdaten geflutet wird.

Die bessere Lösung, um solche Anwendungsfälle zu überprüfen, ist die Nutzung eines virtuellen Dateisystems. Ein virtuelles Dateisystem wird als eigener Stream-Wrapper [1] für PHP erstellt. Damit können Built-in-PHP-Funktionen wie beispielsweise mkdir oder file_exists genutzt werden. Die Library vfsStream [2] bietet genau das. Ein Vorteil liegt darin, dass vfsStream mit nahezu jedem PHP-Testfra...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang