Dieser Artikel schließt die Reihe zum Thema Teststrategien ab. Der Fokus liegt auf dem Thema Testumgebung und damit auf dem automatisierten Testen von komplexeren Systemfunktionen.
Das Ziel der vorgestellten Teststrategien ist eine optimale Integration in den bestehenden Entwicklungsprozess. Zu diesem Zweck werden die folgenden Themen behandelt:
- Was kann effektiv mit Modultests getestet werden? (Testobjekte)
- Wann sollten Tests erstellt werden? (Testzeitpunkt)
- Wie können komplexere Funktionen getestet werden? (Testumgebung)
Testumgebung
In einfachen Fällen wird für einen Test nichts weiter benötigt, als ein paar Aufrufe der zu testenden Funktion. Die übergebenen Parameter definieren die Eingabe und anschließend wird die Ausgabe mit dem erwarteten Wert verglichen. Neben gültigen Werten sollten dabei auch fehlerhafte Werte sowie Grenzwerte übergeben werden, um unwahrscheinliche Konstellationen zu überprüfen.
Es kann aber vorkommen, dass die Ein- und Ausgaben der zu testenden Funktion komplexer sind: Ein Beispiel dafür ist eine Funktion zum Export von Daten in einem definierten Format, wie etwa XML oder JSON. Diese lässt sich nur mit einer gegebenen Datenbasis testen, was auf folgenden Wegen realisiert werden kann:
- Konstanter Datenbestand: Die Tabellen in der Testdatenbank werden einmalig definiert und anschließend nicht mehr verändert. Damit bezieht sich jeder Test auf dieselbe Datenbasis.
- Dynamischer Datenbestand: Die Datenbanktabellen werden vor dem Aufruf der Testfunktion prozedural gefüllt und somit immer die erwartete Datenbasis wiederhergestellt.
Falls Veränderungen an den Datensätzen nicht dauerhaft (über den Test hinaus) in die Datenbank gespeichert werden sollen, können die folgenden Mittel genutzt werden:
- Transaktionen: Vor der Testausführung wird eine Transaktion gestartet (
DtaBegin()
), die anschließend abgebrochen wird (DtaRollback()
). - Nur-Lesen: Die Datenbank wird in den Status „Nur Lesen“ versetzt und damit jegliche dauerhafte Änderung verhindert.
Für das Beispiel des Datenexports sind damit die Eingabewerte in Form von Tabelleninhalten definiert. Um das Exportresultat, also die erstellte XML- oder JSON-Datei, überprüfen zu können, wird noch eine Referenzdatei benötigt. Diese Datei entspricht dem erwarteten Export und kann entweder in der Datenbank (als interner Text) oder in einer externen Verzeichnisstruktur abgelegt werden. Die Testfunktion kann dann die Übereinstimmung der exportierten Datei mit der Referenzdatei überprüfen und somit den Erfolg des Tests beurteilen. Im genannten Beispiel wäre dies über einen zeilenweisen Vergleich beider Texte oder anhand deren Hashwerte möglich.
Fazit
Die in dieser Serie von Artikeln genannten Strategien sollen das Integrieren von Modultests in den Entwicklungsprozess erleichtern. Die Testerstellung kostet zwar Zeit, diese Investition lohnt sich aber mittelfristig. Zum einen wird die Qualität der Software erhöht, da mit steigender Anzahl an Tests auch die Erkennungsgenauigkeit von Fehlern zunimmt. Zum anderen wird Zeit gespart, da Fehler früher erkannt und korrigiert werden können und der Aufwand für manuelle Tests reduziert wird. Als Nebeneffekt wird zudem die Modularität des Quellcodes verbessert, da die automatisierten Tests zur Definition klarer Schnittstellen anhalten.