Das Schreiben von Unit-Tests kann genauso spannend und interessant sein wie die Entwicklung von Software selbst. Dennoch ist es wahrscheinlich, dass wir alle beim Schreiben von Unit-Tests mal gemogelt oder uns selbst angelogen haben. Ich habe jedenfalls genau das getan. Als ich die ersten Unit-Tests geschrieben habe, war ich ganz stolz darauf, dass die Codeabdeckung immer zwischen 90-99% lag. Mit der Zeit habe ich jedoch gemerkt, dass eine gute Codeabdeckung keine Garantie für eine fehlerfreie und sehr stabile Klasse ist. Als Konsequenz daraus habe ich für mich eine Art „Checkliste“ mit Testfällen aufgestellt, die ein gutes Unit-Test auf jeden Fall implementiert haben sollte.
Die Instanz testen
Hier prüfen wir, ob die neu erzeugte Instanz auch die ist, die wir erwarten. Weiterhin können wir hier mögliche Elternklassen, feste Attribute oder auch Methoden innerhalb einer Klasse prüfen, also Abhängigkeiten zu anderen Klassen und Variablen.
Fehlerzustände und Ausnahmefehler testen
Sofern die zu testende Klasse Ausnahmefehler erzeugen kann, sollten diese auch provoziert werden. Werden die Ausnahmefehler wie erwartet geworfen? Dabei könnte man auf die Idee kommen, den einen oder anderen Ausnahmefehler neu zu überdenken. Denn nicht jeder neu definierte Ausnahmefehler stellt auch einen Ausnahmezustand dar. Zum Beispiel beim Bestimmen des richtigen Typs des zu erwartenden Eingabewertes. Hier ist ein „Type Hinting“ oder „Type Casting“ oft der bessere Ansatz. Das ist jedoch von Fall zu Fall unterschiedlich. Was auch gerne beim Testen vergessen wird sind die Fehlerzustände wie: nicht erreichbare SOAP-Schnittstelle, nicht verfügbare Systemressource oder auch eine fehlerhafte Datenbankverbindung.
Der ideale Testfall
Hier ist der Aufruf einer Methode zu prüfen. Alle Vorbedienungen zum Instanziieren der Klasse und zum Aufrufen der Methoden müssen gegeben sein. Dabei dürfen keine Notices oder Warnings von PHP erzeugt werden. Wenn das schon hier passiert, dann stimmt was mit der Klasse von Anfang an nicht. Hier wurde nicht genau gearbeitet. Solche Zustände sollten umgehend nachgebessert werden, bevor der Quelltext in der Versionsverwaltung abspeichert wird.
Minimalwerte testen
Dieser Testfall ist auch als „Minimal Case“ bekannt. Hier werden nur die notwendigsten Parameter mit dem kleinst möglichen Wert übergeben. Für Datumsangaben wie Geburtsdatum könnte das etwa der 1.1.0001 sein, Zeitangaben werden mit 00:00 angegeben. Bei Strings könnte ein Leerstring oder eine einzelnes Zeichen verwendet werden. Damit wird versucht, der Realität des Endanwenders etwas näher zu kommen. Den Minimalfall sollte jeder für sich selbst und abhängig von den Anforderungen des Kunden definieren.
Maximalwerte testen
Beim sogenannten „Maximal Case“ passiert genau dasselbe wie beim Minimalfall, jedoch andersherum. Man setzt hier die höchst mögliche Parameteranzahl mit dem höchstmöglichen Wert ein. Für Datumseingaben etwa den 31.12.9999, bei Zeitangaben 24:00 oder 23:59, oder bei Stringwerten die Zeichenlänge eines Datenbankfeldes sowie Sonderzeichen und UTF-8 Zeichencodierungen. Dieser Testfall ist nicht sehr aufwendig, und im bestimmten Fällen sehr ausschlaggebend wenn es darum geht, sichere Eingabewerte zu bekommen.
Grenzwerte testen
Hierbei versucht man, den Maximal-Testfall und den Minimal-Testfall auszureizen, also über den Wert hinaus zu gehen. Das würde dann so aussehen:
- Maximalwert – 1
- Minimalwert – 1
- Maximalwert + 1
- Minimalwert + 1
Manche Werte werden vielleicht nicht so oft vom Endanwender eingegeben, aber wir sind für den Fall der Fälle gerüstet, wenn wir unsere Klasse vorab drauf vorbereitet haben, entsprechend zu reagieren.
Wie sind eure Erfahrungen? Habt ihr noch weitere Testfälle oder Testmethoden die man noch einsetzen könnte? Schreibt mir, das würde mich interessieren.
Nachtrag: Hier eine Grafik die den Ablauf einzelner Testarten und -phasen sehr gut beschreibt.
Weiterführende Informationen bekommt ihr in der Quality Newsletter – Juni 2004 Schwerpunktthema
Finde, dass ist schon ein sehr guter Ansatz und mir fällt auch spontan keine Ergänzung ein.
Eventuell ob der Destrukt richtig funktioniert, sofern z.B. Resourcen wie Dateien genutzt werden. Beispiel ist z.B. eine gelockte Datei die nicht entlockt wird.
Habe Dich über Google Alerts gefunden. Wir ham ein Tool entwickelt, von dem wir glauben, dass es das Pendant zum Unit-Test sein kann.
Und zwar geht es um Black-Box-Tests, Testpläne, White-Box-Tests, usw.
Ist so was in „Eurer Szene“ auch interessant oder geht es Euch rein um automatisierte Unit-Tests?
Das Tool heißt übrigens Zeta Test“.
@Uwe: Hier geht es eigentlich um PHPUnit-Test. Deine Test-Methoden einschließlich Akzeptanz-Test, werde ich ein anderes mal umschreiben.