Was ist automatisiertes Testen, und warum ist das wichtig?
Über das Testen einer Software wird zu Beginn eines Projekts oft gerne nicht viel nachgedacht. Aber warum sollte man das lieber nochmal überdenken, und wieviel Geld und Zeit kann das tatsächlich ausmachen?
Ein Test in der Softwareentwicklung überprüft, ob die ausgemachten Anforderungen eingehalten werden. Die Ergebnisse durchlaufener Tests werden verwendet, um auf eventuelle Fehler aufmerksam zu werden. In weiterer Folge dienen Softwaretests dazu, das System möglichst fehlerfrei in Betrieb nehmen zu können. Ob nun die Anforderungen eingehalten werden, kann einerseits über manuelle Tests geschehen, andererseits durch automatisierte Tests, ausgeführt durch ein Test-Tool.
Der Unterschied scheint klein
Manuelles Testen erscheint anfänglich als sehr einfache und effiziente Methode, um Funktionen zu verifizieren. Dies kann einerseits durch den Entwickler selbst geschehen, indem er seine Veränderungen ausprobiert und durchklickt und/oder mit den Eingabeparametern variiert, um auch Fehler zu provozieren. Andererseits gibt es für genau solche Aufgaben eine eigene Rolle/Position: den Tester. Dieser verifiziert anhand von detaillierten Beschreibungen die einzelnen Bestandteile der Software.
Automatisierte Tests werden im Gegensatz völlig autonom, unabhängig von Zeit und Ort durch ein Test-Tool in einer isolierten Testumgebung ausgeführt. Eine Testumgebung ist beispielsweise ein temporärer PHP-Server und einer Datenbank mit Test-Daten. Um solche Tests zu entwickeln, sind in den meisten Fällen Programmierkenntnisse notwendig. Automatisierte Tests ermöglichen zu jeder Zeit einen Überblick, ob sich das System oder auch nur einzelne Komponenten davon richtig verhalten. Dafür muss sichergestellt werden, dass die auszuführenden Tests korrekt funktionieren. Dies geschieht in der Regel durch manuelle Tests in denen der jeweilige Test genau analysiert und während der Ausführungszeit beobachtet wird.
Von Klein bis Groß
In Softwaresystemen gibt es in der Regel verschiedene Komponenten: Datenbank/Datenspeicher, Businesslogik, grafische Oberfläche(n) etc. Entsprechend dazu gibt es auch verschiedene Arten von Tests: (gängige Arten für automatisierte Ausführung)
- Unit Test, die kleinste und schnellste Version eines Tests: Bei einem Auto können wir testen, ob der Lenkeinschlag stimmt, sobald wir nach links oder rechts lenken. Oder ob das Fahrzeug beschleunigt, wenn wir das Gaspedal durchdrücken. Unit Tests befinden sich immer innerhalb einer Komponente und testen nur eine einzige Funktion.
- Integration Test: Wollen wir das Zusammenspiel verschiedener Komponenten überprüfen, so befinden wir ins im Rahmen eines Integration Tests. Hier können verschiedene Bedingungen simuliert werden. Beispielsweise kann sich unser Auto auf eine Kreuzung mit roter Ampel hinbewegen. Dabei erwarten wir uns konkret, dass es vor der Haltelinie stehen bleibt und solange die Ampel rot leuchtet nicht weiterfährt.
- End-To-End Test (E2E): In dieser Stufe des Testens betrachten wir das Softwaresystem als Ganzes, jedoch nicht live/produktiv sondern mit simulierten Daten. Vergleichbar dazu ist eine Zivilstreife, die das Verkehrsgeschehen beobachtet. Sie verhängt aber keine Strafen, sondern benachrichtigt nur, dass an jener Stelle die Regeln X und Y nicht eingehalten wurden.
Kurz und knackig
Genau so wie ein guter Unit Test ist auch der Hauptgrund für automatisiertes Testen so aussagekräftig und kurz wie möglich: Automatisiertes Testen ist unbedingt erforderlich, um Release-Intervalle kurz halten zu können.
Alles im Überblick
Automatisierte Tests können gegenüber von manuellen jederzeit ausgeführt und das Ergebnis abgerufen werden. Dieser Vorgang dauert für gewöhnlich wenige Sekunden bis hin zu mehreren Minuten, je nach Simulationsaufwand und Projektgröße. Daraus folgt, dass wir all unsere Komponenten, deren Zusammenspiel und das Softwaresystem als Ganzes jederzeit im Blick haben. Je größer das Projekt und länger die Laufzeit, desto mehr kommt dieser Überblick zum Tragen.
Angenommen ein neues Feature kommt zur Software hinzu: Beispielsweise möchten wir den Straßenverkehr um eine Straßenbahn erweitern. So müssen wir die Schienen in die Straßen integrieren, Haltestellen und eigene Ampeln aufbauen, neue Vorrangregeln definieren, die bestehende Ampelschaltung anpassen etc. Solch ein Feature hat große Auswirkungen auf das bestehende System und muss umfänglich getestet werden. Und genau hier beginnt das manuelle Testen aufwändiger zu werden. Mit jedem neuen Feature summieren sich die Testaufwände auf. Wenn nun nicht mehr früh genug eingegriffen wird, bleibt kaum mehr Zeit und Budget für die eigentlich gewünschte Funktionalität übrig, da die meisten Ressourcen in die Aufrechterhaltung des bestehenden Systems fließen.
Test Driven Development (TDD)
Sobald in einem Entwickler-Team TDD etabliert ist - also automatisiertes Testen zur Gewohnheit wird - sinkt die Fehlerdichte verglichen zu einem Team ohne automatisierten Tests um bis zu 90%. Vereinfacht gesagt: Es passieren bis zu 90% weniger Fehler (laut einer Studie von Microsoft und IBM). Diese Fehler werden in frühen Projektphasen gefunden und sparen so Zeit, Nerven, Stress und Opportunitätskosten.
Noch dazu erhöht sich die Zufriedenheit am Arbeitsplatz (laut Stack Overflow Developer Survey 2019). Die Qualität des produzierten Quelltextes steigt automatisch und doch unbewusst, denn leichte Testbarkeit erzwingt gute Wartbarkeit und eine saubere Struktur. Noch dazu können sich neu ins Projekt kommende Entwickler leichter einfinden, da sie sich lediglich die geschriebenen Tests durchsehen müssen, um ein Bild vom Softwaresystem zu erhalten. Folgende Grafik zeigt schematisch, dass dieser anfängliche Aufwand den Charakter eines Investments hat.
Durch dieses Investment legt jeder Auftraggeber den Grundstein dafür, dass das Projekt in der Entwicklung langfristig gut performen kann.
Jedoch ist der Aufwand und die somit verbundenen Kosten am Beginn eines Projekts höher, bedingt durch die Einrichtung der Testumgebungen, Einarbeitung in die Test-Suite und das Erstellen erster Tests.
Ich verzichte lieber darauf…
Ohne einen stetigen Überblick, ob die Software korrekt funktioniert, riskierst du eine immer zäher werdende Weiterentwicklung. Das kommt daher, dass bei jedem neuen Feature die ganze bestehende Software manuell durchgetestet werden sollte, um sicherzustellen, dass noch alles läuft und nichts beeinflusst wurde. Sollte das über längere Zeit so laufen, riskierst du unzuverlässige und vielleicht gar unverwendbare Software. Ab solch einem Stadium ist es auch zwecklos, sich weitere Entwickler mit ins Boot zu holen, da die in der Zwischenzeit aufgebaute technische Schuld so groß sein kann, dass neue, noch so kleine Features mehr Kosten verursachen, als das ursprüngliche Projektangebot.