Grünes Gefühl mit TYPO3
Eine Einführung in Unit-Testing für Extensions
Irgendwann gelangt jeder Entwickler an den Punkt, an dem er überlegt, ob es sich eher lohnt, den angestaubten Code zu überarbeiten oder noch einmal frisch von vorne zu beginnen. Vor allem bei der Übernahme eines fremden Projekts überwiegt oft der Drang nach einem Neuanfang. Es würde meist viel zu lange dauern, den Code aufzuräumen und bei jeder kleinen Änderung könnten sich Fehler einschleichen, die später aufwändig nachvollzogen und bereinigt werden müssten.
Die Arbeit an einer API (Application Programming Interface) ist besonders heikel, denn dort stellt sich die Frage nach einem Neuanfang erst gar nicht: Es gilt, möglichst abwärtskompatibel zu bleiben, denn viele andere Anwendungen sind von der Schnittstelle abhängig. Die Aufräumarbeiten in solchen Programmteilen gleichen daher oft dem Spaziergang auf einem Minenfeld.
Programmieren mit Netz
Die Lösung für diese Probleme heißen „Refactoring“ und „Unit Testing“. Bei „Refactoring“ handelt es sich um die Veränderung der inneren Struktur eines Programms, bei dem sich das äußere Verhalten nicht verändert. „Unit Tests“ dienen dabei als Sicherheitsnetz und geben dem Entwickler eine Rückmeldung darüber, ob einzelne Teile seines Programms noch die gewünschten Resultate liefern.
Unit Tests überprüfen jeweils einen ganz bestimmten Teil einer Software, typischerweise das Ergebnis einer oder mehrerer Methoden. Funktionale Tests, die hier nicht behandelt werden, überprüfen hingegen die Funktionen einer Software als Gesamtheit aus Sicht eines Anwenders.
Unit Testing für TYPO3
PHPUnit [1] von Sebastian Bergmann ist ein Unit Testing Framework das es ermöglicht, eine große Reihe von Tests zusammenzufassen und nacheinander ablaufen zu lassen.
T3Unit ist eine Erweiterung für TYPO3, die auf PHPUnit2 aufbaut und um ein Interface sowie einige Funktionen erweitert ist, die speziell für TYPO3 notwendig sind. Die Extension basiert auf PHP5 und wurde für das Refactoring des Extension Repositories entwickelt. Sie wird auf der TYCON3 im September vorgestellt und veröffentlicht.
Ein Hello-You-Beispiel
Am besten verwendet man Unit-Tests bereits bei der Entwicklung von neuem Code und nicht erst beim Refactoring.
Angenommen es soll eine Funktion geschrieben werden, die einen Namen als Parameter akzeptiert und als Resultat „hello $name“ liefert. Bevor man diese Funktion programmiert, würde man einen Test schreiben, der die spätere Methode überprüft:
public function test_helloYou() {
$exampleObj = new tx_example;
$result = $exampleObj->helloYou ('robert');
self::assertEquals ($result, 'Hello robert', 'The result of helloYou() was not as expected!');
}
Listing 1
In Zeile 2 wird eine Instanz der Klasse erzeugt, die getestet werden soll, um danach die zu testende Methode aufzurufen und das Resultat zu speichern. Schließlich wird eine PHPUnit-Funktion aufgerufen, die das gelieferte Ergebnis mit dem Soll-Ergebnis vergleicht – wenn dieses vom erwarteten Wert abweicht wird eine Fehlermeldung ausgegeben.
Beim Ausführen dieses Tests wird der PHP-Interpreter mit einem „Fatal Error“ darauf aufmerksam machen, dass die Klasse „tx_example“ gar nicht existiert. Diese muss zunächst angelegt werden:
class tx_example {
public function helloYou ($name) {
}
}
Listing 2
Nach erneutem Aufrufen des Unit-Tests wird folgende (erwartete) Fehlermeldung ausgegeben:
Der Unit-Test ist nicht erfüllt, da die Methode „helloYou“ kein Ergebnis zurück liefert, der Unit-Test jedoch eines erwartet.
Im letzten Schritt sorgen wir nun dafür, dass der Test sein erwartetes Ergebnis erhält:
class tx_example {
public function helloYou ($name) {
return 'Hello '.$name;
}
}
Listing 3
Die TYPO3-Extension „T3Unit“ belohnt erfolgreiche Testverläufe mit einem grünen Fortschrittbalken im Backend:
Test Driven Development
Das Besondere an diesem Vorgehen ist, dass ein Test geschrieben wird, bevor die zu testende Funktion überhaupt existiert. Man konzentriert sich von Anfang an auf das gewünschte Ergebnis und sorgt so dafür, dass dieses auch geliefert wird.
Während der weiteren Arbeit sammeln sich so eine ganze Reihe von Tests an, die immer wieder ausgeführt werden. Auf diese Art und Weise kann sichergestellt werden, dass alle wichtigen Funktionen auch nach größeren Änderungen im Quellcode korrekt ablaufen.
Die Methode des „Test Driven Development“ [2] ist ein Baustein des Extreme Programming (XP) [3], das eine bessere Produktivität und Erfolg von Softwareprojekten zum Ziel hat.
Fazit
Unit Testing ist weit mehr als ein gut gemeinter Trend. Viele Aufgaben, wie die Umstrukturierung existierenden Codes, sind ohne solide Tests zeitaufwändig und schwer kontrollierbar. Auch wenn es auf den ersten Blick nicht so aussieht wird die zusätzliche Arbeit für die Programmierung eines Tests schnell mit einem großen Zeitgewinn durch den Wegfall langer „Debug-Sessions“ belohnt. Ein weiterer Faktor, der nicht zu unterschätzen ist, scheint psychologischer Natur zu sein: Unit Tests geben dem Entwickler eine gewisse Sicherheit und Souveränität. Wer eine Zeit lang mit Tests gearbeitet hat, wird das gute Gefühl beim Erscheinen des grünen Balkens nicht vermissen wollen. Hektische „Debug-Sessions“ vor dem Launch einer Website sollten somit der Vergangenheit angehören.














