Call again – PHPUnit Test driven Development Watcher

Wer Test Driven Development in PHP betreibt findet kaum Lösungen für das automatische Starten von PHPUnit nach Datei- bzw. Quellcode Änderungen. Da das Wechseln des Tabs und das Ausführen meist einige Sekunden dauert, habe ich mir die Aufgabe gestellt diese Zeit zu sparen. Entstanden ist so ein File-Watcher der auf Dateiänderungen reagiert und PHPUnit automatisch startet.

FileWatcher in PHP / Ausführung von PHPUnit

Für die meisten Betriebssysteme gibt es sogenannte Notifier (Beispielsweise inotify für Linux), die auf Änderungen im Dateisystem reagieren und eine Änderung melden. Dieses System bietet sich natürlich an um auf die Dateiänderungen zu reagieren und um PHPUnit zu starten. Durch die unterschiedliche Implementierung von Windows, Linux, und OS-X habe ich mich für JNotify, eine Java Variante entschieden, die Plattformunabhängig ist. Da wir mit PHP entwickeln, ist es schwierig die Systembibliotheken zu verwenden. Ich muss dazu PHP-Module installieren, was bewirkt das die Installation des Tools erschwert wird. Damit habe ich keine einfach zu installierende Lösung mehr.

Erste Idee

Mein erster Ansatz war einfach auf die Änderungszeit der Datei zu achten. Dazu habe ich eine Endlosschleife geschrieben die alle PHP-Dateien in einem Verzeichnis durch iteriert und dann die Dateizeit vergleicht. Sobald eine Änderung vorlag wurde PHPUnit gestartet. Mir war bewusst das diese Art suboptimal ist und Last auf dem Betriebssystem erzeugt. Für die erste Version war dies vorerst nicht wichtig, denn selbst mit der Lösung konnten wir den File Watcher schnell in den Betrieb aufnehmen. Da die zu überwachenden Ordner mit der Zeit natürlich immer größer wurden, ist der Watcher immer langsamen geworden. Das ist ja auch logisch, da rekursiv jede Datei betrachtet werden muss.

Implementierung JNotify

Die Hauptarbeit hatte ich schon mit dem ersten Release erledigt, somit musste nur noch der Main Loop ersetzt werden. Das JNotifiy Programm wird so gestartet das ein Dateizeiger zum Lesen der Änderungen zur Verfügung steht. Der Main Loop ist ab jetzt eine blockierende Schleife, die auf Ausgaben des JNotify wartet. Wird eine Änderung an einer PHP Datei festgestelt, wird PHPUnit gestartet.

Entwicklung als PEAR Packet

Wie oben schon erwähnt sollte das Tool einfach und schnell zu installieren sein. Dafür bot sich der PEAR Package Manager an. Das Generieren von PEAR Paketen wird über eine package.xml realisiert. In der XML Datei können alle wichtigen Einstellungen vorgenommen werden (Meta Informationen, Dateien, Voraussetzungen wie zum Beispiel die PHP-Version).

Das Bereitstellen des Paketes übernimmt Pirum, ein PEAR Channel Server Management Tool. Auch hier wird die Konfiguration wieder in eine XML Datei abgelegt und dann über einen kurzen Befehl released. Hierzu empfehle ich Jeden sich die Dokumentation von Pirum ansehen.

Build Prozess

Der Build Prozess des PEAR Paketes ist komplett in Phing geschrieben. Somit muss ich nur noch den Befehl “phing” auf der Konsole eingeben und das fertige Paket ist erstellt. Über Phing werden wir demnächst sicher noch weitere Blogartikel schreiben.

Installation

Der Quellcode und auch eine kleine Anleitung sind auf http://www.github.com/Scyks/TDDRunner zu finden. Wer jedoch die PEAR Version nutzen möchte kann das Tool wie folgt installieren:

pear channel-discover pear.ceow.de
pear install ceow/TDDRunner

Besonderheiten auf 64 Bit Linux Systemen

Die JNotify Bibliothek benutzt standardmäßig die 32 Bit Version welche Fehler in der Ausführung verursacht. Um die 64 Bit Version zu nutzen musst Du nur die folgende Schritte anwenden.

  1. Neuer Ordner “32-bit_Linux” im “jnotify-lib-0.94” anlegen (/usr/share/pear/TDDRunner/jnotify-lib-0.94)
    cd /usr/share/pear/TDDRunner/jnotify-lib-0.94
    mkdir 32-bit_Linux
  2. Die libjnotify.so in den 32-bit_Linux Ordner verschieben
    mv libjnotify.so 32-bit_Linux/libjnotify.so
  3. Einen Symbolischen Link der 64-Bit Version anlegen
    ln -s 64-bit_Linux/libjnotify.so libjnotify.so

Benutzung für PHPUnit

Für die Verwendung des Programms muss man nur den Befehl “tddrunner” ausführen. Dann wird direkt in dem Verzeichnis in dem man sich befindet auf Änderungen reagiert und in diesem Verzeichnis PHPUnit ausgeführt. Diese Einstellungen können jedoch konfiguriert werden.

  • –watch-path <path> Verzeichnis in dem Änderungen registriert werden sollen
  • –test-path <path> Verzeichnis in dem PHPUnit ausgeführt werden soll
  • –phpunit-path <path> Pfad zum PHPUnit Programm sofern nicht /usr/bin/phpunit
  • * Alle anderen Konfigurationen werden 1:1 an PHPUnit weitergeben, wodurch man PHPUnit konfigurieren kann.

Beispiele:

  • Reagiert rekursiv auf Dateiänderungen im aktuellen Ordner und führt dann in diesem PHPunit aus
    tddrunner
  • Reagiert rekursiv auf Dateiänderungen in “my/Project/Foler”
    tddrunner -watch-path /my/Project/Folder
  • Reagiert rekursiv auf Dateiänderungen in “my/Project/Foler” und Führt PHPUnit in “my/Project/Folder/Tests” aus
    tddrunner -watch-path /my/Project/Folder --test-path /my/Project/Folder/Tests
  • Definiert, dass PHPUnit in “/var/phpunit” liegt
    tddrunner --phpunit-path /var/phpunit
  • führt PHPUnit mit der Option “–group=test” aus
    tddrunner --group=test

Fazit

Es sind immer die kleinen Dinge die einem die Arbeit erleichtern. Ich spare mit solch einem Tool einiges an Zeit und Nerven und kann angenehm entwickeln. Gerade wenn die Möglichkeit besteht an 2 Monitoren zu arbeiten ist dies schon fast unverzichtbar. Ich empfehle jedem Entwickler ein solches Tool einzusetzen, denn es erleichtert die Arbeit und legt den Fokus auf das Wesentliche.

Happy Coding

 

2 responses on “Call again – PHPUnit Test driven Development Watcher

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.