Continuous Testing mit PHP?
Continuous Integration ist einigen eventuell ein Begriff. Dabei geht es darum, einen Server zu haben der bei jedem Commit (bzw. Push) des Quelltextes Dinge ausführt wie Unit Tests, Akzeptanz-Tests, PHP Lint, CodeSniffer oder auch ein Deployment auf einen Test-Rechner. Wenn man nun also häufig pushed kann man sicher sein dass (bei genügend guten Tests) die Software läuft und nichts kaputtgegangen ist. Und wenn doch, weiß man wann es ungefähr passiert ist.
Continuous Testing geht nun noch einen Schritt weiter. Hierbei werden nicht erst bei jedem Push die Unit-Tests gestartet sondern bei jedem Abspeichern einer Datei auf dem Entwicklungsrechner. Da gibt es nun mehrere Ansätze wie man das erreichen kann. Vielleicht kennt ihr andere und bessere Tools, um kontinuierlich auf der Workstation zu testen.
Möglichkeit 1: Die IDE bietet einen „On-Save“ Einstellung, wo man einen Befehl eingeben kann der ausgeführt wird sobald die IDE eine Datei abspeichert. Dort trägt man dann sein Shell-Script ein das die Unit-Tests startet. in PHPStorm kann man zum Beispiel auch einstellen dass nach 15 Sekunden IDLE automatisch gespeichert wird, oder wenn PHPStorm den Fokus verliert (weil man gerade in den Browser wechselt). Ein Garant für häufiges Testen.
Möglichkeit 2: Man nutzt Eclipse und installiert das Plugin PTI, um PHPUnit, PHP_CodeSniffer, PHP_Depend und PHP Copy&Paste Detector direkt in Eclipse zu integrieren. In PHPStorm ist eine PHPUnit-Integration direkt eingebaut und man kann dann direkt die aktuelle Klasse, Methode, die Datei oder das ganze Verzeichnis testen lassen. Ergebnisse werden in beiden Fällen direkt in der IDE angezeigt. Ich glaube ähnliches gibt es auch in NetBeans.
Möglichkeit 3: Ein kleines externes Programm beobachtet das Projektverzeichnis. Sobald sich eine Datei geändert hat werden die Tests ausgeführt. Aus der Ruby-Welt gibt es da Auto-Test und Watchr, die aber auch für PHP-Projekte benutzt werden können. In PHP geschrieben habe ich so etwas noch nicht gefunden, es müßte aber möglich sein. Falls es Unterstützung für die Inotify-Extension gibt geht es eventbasiert, ansonsten muss man eine Schleife laufen lassen die die filemtime() aller Dateien beobachtet.
Ein interessantes Linux-Tool ist incron, das ähnlich wie das normale cron Befehle ausführen kann. Im Gegensatz zu cron führt incron jedoch Aktionen nicht zeitlich gesteuert aus sondern wenn es inotify-Events vom Dateisystem gibt. Man kann damit erreichen dass beim Erstellen, Ändern oder Löschen einer Datei in unserem Projektordner Befehl X ausgeführt wird.
Bei diesen externen Tools muss natürlich auch eine sichtbare Ausgabe erfolgen. Dazu kann man auf Workstations natürlich einen Sound abspielen, oder gleich fertige Dinge wie Growl nutzen, die einem diese schönen kleinen Kästen rechts unten hochfahren lassen.
Wer von euch testet kontinuierlich (automatisiert) auf seiner Workstation?
Ich habe öfters einfach eine Shell mit phpunit in ner schleife offen und nem sleep, so läuft die test-suite lokal immer wieder durch mit ner pause dazwischen durch, auf nem system mit mehr als einem core ist das meistens kein problem, fails produzieren ein popup-fenster mit dem phpunit-output, vor allem „stoppt“ es dann auch und man kann es dann einfach neu starten.
Soetwas fest über die IDE oder ähnliches on-save zu machen hat bei mir irgendwann auf das verhalten abgefärbt dass ich weniger speicher, damit der nutzen der IDE-internen File-history weniger wird (nutze ich ab und zu auch ganz gerne um mal zu schauen wie sich die lösung über den verlauf angepasst hat, ohne für jede Änderung einen commit zu haben).
Ausserdem – so sehr man es mag – kommt es durchaus auch mal vor dass man einen oder mehrere tests kaputt macht – es weis – aber erstmal eine/mehrere andere stelle ändern muss (z.b. auch refactorings über die IDE) und da ist es dann auch nervig wenn bei jeder Datei die man speichert die suite automatisch wieder abläuft, obwohl man weis dass es noch X mal speichern dauern wird bevor man wieder grün bekommt, das lenkt dann zu stark ab.
Mein einfacher einzeiler für linux:
while true; do FOO=`/usr/bin/phpunit`; if [ $? -ne 0 ]; then xmessage -center „$FOO“ & break; else sleep 5; fi; done
Siehe auch:
http://www.robo47.net/blog/201-Running-phpunit-in-a-loop-and-let-it-inform-you-when-you-broke-something
robo47
5 Aug 11 at 12:53
Ne „lokale“ Installation eines CI-Servers, welche das Filesystem auf Veränderung überprüft, mit ’ner einstellbaren Wartezeit, wäre in meinen Augen ebenfalls denkbar.
Vor allem, wenn man mehrere Projekte gleichzeitig im Auge behalten möchte.
RennerC
5 Aug 11 at 13:05
pywatch phpunit ./source ./tests
oder ohne scrollen
pywatch „clear && phpunit“ ./source ./tests
edorian
5 Aug 11 at 18:08
Würde mich persönlich wahnsinnig machen und genau wie robo vom Speichern abhalten. Was nicht nur für die History schlecht ist, sondern vor allem, wenn einem mal die IDE abschmiert.
nk
5 Aug 11 at 20:48
Ich hab mir ne virtuelle Maschine eingerichtet auf der ich PHPUnderControl eingerichtet habe.
Als Sourceverwaltung nehm ich GIT her, hierfür gibts bestimmt auch geeignete Hooks-Scripts die bei Update den Build starten.
Ansonsten den Build einmal oder zweimal täglich automatisch vom Buildserver durchführen lassen.
PHPUndercontrol arbeitet mit PHPUnit, PHP-Depend, PHPMD, CodeSniffer und PHPDoc, Doxygen hab ich auch in den Buildprozess reinbekommen, aber leider noch nicht in die Übersicht von PHPUndercontrol.
Alexander Jonser
6 Aug 11 at 09:00
hat jemand genauere Erfahrungen mit PHPUnit, PHP_CodeSniffer, PHP_Depend und PHP Copy&Paste Detector in Eclipse.
Hab das mal installiert, und mein Rechner is halb abgeraucht, entwickeln war nicht mehr möglich, Eclipse is auch ohne die Tools ziemlich langsam.
Weis jemand was für ne Power meinen PC braucht, damit da die ganzen Tools einwandfrei laufen?
fishbonebob
8 Aug 11 at 09:25
Weil Entwickler viel zu faul sind dauernd darauf zu achten oder den Test auszufuehren, muss man es ihnen einfach immer wieder vor die Nase halten. Ich fand den pywatch-Ansatz gut, nur laeuft der eben auch in einem Terminal im Hintergrund.
Aus dem Ansatz hab ich gestern schnell https://github.com/hpbuniat/testy gebaut. Macht das gleiche + growl notifier. Das funktioniert dann auch, wenn man unter Windows ueber samba, shared-folders, etc.
Hans-Peter Buniat
8 Aug 11 at 20:12
[…] Ausgabe des eCommerce-Podcasts erschienen.Entwicklung allgemeinDer PHP Gangsta schreibt über Continuous Testing mit PHP. Mich würde es wahnsinnig machen, wenn bei jedem Speichern der Datei getestet wird, aber wer drauf […]
Links 34/2011: Magento, e-Commerce und Entwicklung allgemein
22 Aug 11 at 07:17