Verschiedene Softwaretestverfahren: Explorative, manuelle, automatische Tests sowie Unit- und Integrationstests

Softwaretests sind nicht umsonst ein großes Gebiet, denn dahinter stecken Erfahrungen, Wissen, Konzepte und – wie könnte es anders sein – auch ein Haufen Arbeit. Hier wollen wir kurz in die einzelnen Bereiche des Softwaretests hineinblicken und uns für unsere Python-Projekte die notwendigen Kenntnisse anschaffen.

Manuelle Tests

Von allen Arten sind die manuellen Tests die intuitivsten, denn als Programmierer schreibe ich Code und führe diesen anschließend aus, um zu prüfen, ob das Geschriebene fehlerfrei ist und auch auf die Art und Weise arbeitet, wie ich zuvor als Annahme getroffen habe. Im Gegensatz zu automatischen Tests führt man die manuellen Tests als Mensch aus – händisch, wie es der Name schon andeutet. Das kostet Zeit und Aufmerksamkeit, ist aber während der Entwicklung unvermeidbar.

Explorative Tests

Ähnlich intuitiv sind explorative Softwaretests. Hierbei probiert eine Person verschiedene Bereiche der Software aus. Sie verwendet das Programm einfach so, wie es auch ein normaler Anwender tun würde, so haben die Texterinnen und Tester freie Hand, was die eigentliche Verwendung angeht. Hierbei ist es auch möglich, den testenden Personen eine sehr grobe Vorgabe zu geben. Beispielsweise könnte man sagen, dass ein Bildbearbeitungsprogramme auf die Art getestet werden soll, dass ein Bild in Schwarz-Weiß als JPG gespeichert wird. Hierzu müssen die Texterinnen und Tester das Programm starten, ein Bild laden, es womöglich in Schwarz-Weiß wandeln und beim Speichern des Ergebnisses das Format JPG auswählen. Wo sich die benötigten Funktionen im Programm befinden und wie sie funktionieren, erzählt man den Personen jedoch nicht. Auf diese Weise kann man sehen, wie gut sich die Software bedienen lässt und ob die unterschiedlichen Funktionen auch tatsächlich funktionieren. Explorative Softwaretests sind aufwändig und können lange dauern, automatische Tests sind hier willkommene Helfer.

Automatische Tests

Wenn Computer etwas haben, dann ist es die Fähigkeit, unermüdlich repetitive Aufgaben auszuführen. Insofern ist es absolut naheliegend, den Computer mit der Aufgabe zu betreuen, die richtige Funktionsfähigkeit von Code sicherzustellen, indem man den Rechner die Software automatisch testen lässt.

Komponenten- oder Unittests

Hierfür bietet es sich an, bereits während der Entwicklung mit Komponententests – auch Unittests genannt – zu arbeiten.

Am schönsten ist es, wenn wir mit den Tests beginnen, noch bevor wir die eigentliche Funktion geschrieben haben. Dieser Ansatz nennt sich testgetriebene Entwicklung (Test-Driven Development, TDD). Hierbei schreibt man erst den Test der zu implementierenden Funktion und führt den Test anschließend aus. Dieser schlägt natürlich fehl, weil es die Funktion ja noch gar nicht gibt. Nun schreibt man den Code und führt abermals den Test aus. Ist der Test erfolgreich, ist die Funktion fertig, falls der Test immer noch fehlschlägt, bessert man die Funktion nach, bis der Test erfolgreich durchläuft. Mit diesem Ansatz stellt man sicher, dass die Software in getesteten und gleichzeitig überschaubaren Einheiten entsteht.

Ein weiterer Vorteil ist nun, dass diese Komponententests immer zur Verfügung stehen, so dass man sie jederzeit ausführen kann, um zu prüfen, dass der gesamte Code noch funktioniert. Es empfiehlt sich, einen Rhythmus zu finden, in dem man diese Tests periodisch ausführt. Beispielsweise könnte man es sich zur Regel machen, alle Komponententests laufen zu lassen, wenn man mit einer Aufgabe fertig ist, bevor man den Code ins Versionskontrollsystem stellt. Auf diese Weise stellt man sicher, dass der neue Code keine anderen Stellen der Software zerstört hat.

Eine weitere passende Gelegenheit bietet sich an, wenn die Entwicklerin oder der Entwickler eine Aufgabe beendet und ins Versionskontrollsystem geladen hat. Dort werden die Tests anschließend automatisch ausgeführt und man bekommt eine Nachricht, falls einer oder mehrere Tests fehlschlagen. Dieser Ansatz ist sogar der bevorzugte, weil er der Entwicklung die Arbeit abnimmt, an die Tests zu denken und sie auszuführen.

Integrationstests

Nun ist der erfolgreiche Durchlauf von einer Reihe von Unittests keine Garantie dafür, dass die Software wie gewünscht funktioniert. Schließlich kann jede Funktion für sich sinnvolle Ergebnisse liefern, aber das Zusammenspiel der vielen Funktionen dennoch fehlerhaft sein, wie dieses Beispiel zeigt:2 unit tests. 0 integration tests. Der Riegel des Schlosses lässt sich vor- und zurückschieben, aber die eigentliche Aufgabe – das Verriegeln der Tür – wird nicht erfüllt.

Integrationstests sind also dazu da, zu untersuchen, ob die einzelnen Komponenten, woraus ein Programm besteht auch untereinander greifen und zu definierten Ergebnissen kommen. Somit finden sie eine Ebene oberhalb der Unittests statt, da sie viele dieser Tests zusammenfassen und die Koordination der Einzelteile des Systems prüfen.

Integrationstests können manuell von damit beauftragen Personen ausgeführt werden, allerdings bietet es sich mit zunehmender Komplexität der Software an, auch die Integrationstests zu automatisieren. Die automatisch ablaufenden Integrationstests sollten ähnlich wie die Unittests regelmäßig laufen. Da sie teilweise recht aufwändig und zeitintensiv werden können, bietet es sich an, diese Tests in der Nacht laufen zu lassen, so dass am nächsten Morgen eine Nachricht im Postfach liegt, falls bei der Ausführung der Tests etwas schief gegangen sein sollte.

Weitere Testverfahren

Neben den hier bisher genannten Verfahren gibt es noch eine Reihe weiterer Tests wie beispielsweise der Regressionstest, der Systemtest, der Abnahmetest und mehr. Wir beschränken uns hier aber im Wesentlichen auf den Komponententest, denn diese Art von Test gehört heutzutage zur Pflicht einer jeden Entwicklerin / eines jeden Entwicklers.

Nachdem wir uns bereits damit beschäftigt haben, warum man überhaupt Softwaretests schreibt und welche Arten von Tests es allgemein gibt, sehen wir uns im nächsten Post das Schreiben verschiedener Tests in Python genauer an.

Photo by Sarah Pflug from Burst