<p dir="ltr">“Ist die App nicht irgendwann fertig?” - Diese Frage wird mir als Softwareentwickler bei typedigital häufig seitens der Kunden gestellt. Diese Frage ist durchaus berechtigt, denn digitale Produktentwicklung, wie die von Apps, unterscheidet sich in Bezug auf die Finalisierung von Projekten maßgeblich von der Finalisierung klassischer Projekte. Zum Beispiel beendet ein Schreiner seine Arbeit mit einem funktionsfähigen Möbelstück, ein Maurer mit einem wetterfesten Rohbau und ein Koch mit einem Gericht, welches er zum Gast bringen lässt.</p>
<p dir="ltr">Warum schaffen wir Softwareentwickler es nie, unsere Projekte so zu beenden, wie klassische Projekte beendet werden?</p>
<p dir="ltr">Anstatt die Zahlreichen komplexen Interaktionen von unserem Code mit anderer Software, Hardware, externen Anbietern etc. aufzuschlüsseln, bietet folgendes Statement einen ersten Erklärungsversuch:</p>
<p dir="ltr">“WhatsApp wird von Meta, dem Konzern hinter Instagram und Facebook gebaut und sogar die bekommen ihre Software nicht frei von Fehlern.”</p>
<p dir="ltr">Eine komplexe Software zu schreiben, die 100% frei von Fehlern ist, ist nahezu unmöglich. Immer wieder treten sogenannte “Bugs”, also Fehler oder Störungen im Code auf, die dafür sorgen, dass das Programm nicht wie erwartet funktioniert.</p>
<p dir="ltr">Was jedoch durchaus möglich ist, den Code mittels Softwaretests so zu testen, dass es die meisten dieser Bugs nie zum Nutzer schaffen, sondern bereits vorher beseitigt werden. Und wer die richtigen Methoden hierfür von Beginn an beherzigt, wird am Ende mit einer Fehler-Resilienten und soliden Software belohnt.</p>
<h2 dir="ltr">Test Driven Development</h2>
<p dir="ltr">Der Begriff “Test Driven Development” sollte heute, in der Welt der IT, niemandem mehr fremd sein. Seinen Code auf anforderungsbasierte Tests zu stützen, verringert langfristig Kosten, da der Wartungsaufwand und die Dauer der Fehleranalyse stark reduziert werden.</p>
<h2 dir="ltr">Automatisiertes Testing</h2>
<p dir="ltr">Wenn in diesem Beitrag von Software-Testing gesprochen wird, sind vor allem automatisierte Tests gemeint. Das bedeutet, dass die Anforderungen an die Software in Form von Tests in den Code einfließen. Diese Prüfung von neu geschriebenem Code kann während des Entwicklungsprozesses eingesetzt werden, um Fehler zu erkennen, bevor den Usern das Programm zur Verfügung gestellt werden soll. Durch solch ein Vorgehen lassen sich laut Frühauf et al. “85% der Fehler beseitigen”¹, und das für einen geringen Kostenaufwand. Zieht man in Betracht, dass Bugfixing wesentlich kostspieliger ist und Fehler in der Software die Nutzer-Erfahrung so einschränken würden, dass die Nutzer das Produkt ablehnen könnten.</p>
<h2 dir="ltr">Die Bausteine eines guten Testsystems</h2>
<p dir="ltr">Als Agentur für digitale Produkte arbeiten wir in unserer Softwareabteilung mit drei unterschiedlichen Arten von Tests: Unit-Tests, Integration-Tests und System-Tests (End-to-End-Tests).</p>
<p dir="ltr">Bei Unit-Tests geht es darum, einzelne Funktionen und Methoden unseres Programms isoliert zu testen, um die Funktionsfähigkeit des Codes schnell und unkompliziert zu überprüfen.</p>
<p dir="ltr">Der Nachteil ist hier, dass die Interaktion mit anderen Funktionalitäten letzten Endes trotzdem für Fehler sorgen könnte. Diese Interaktion zwischen Modulen und Services zu testen, bezeichnet man dann als Integration-Tests. Wir stellen sicher, dass unsere Komponenten richtig zusammenarbeiten und dass bei deren Interaktion das von uns gewünschte Verhalten auftritt. Solche Tests zu schreiben dauert länger, ist ein wenig komplexer und deckt hierbei trotzdem nicht alle möglichen Interaktionen ab.</p>
<p dir="ltr">Wollen wir sicherstellen, dass aus Sicht des Nutzers alles läuft wie gewünscht, können wir auf Systemtests zurückgreifen. Bei dieser Art von Test prüfen wir die Funktionalität des Systems als Ganzes und dessen Interaktion mit externen Systemen. Somit können wir als Entwickler feststellen, ob alles funktioniert, ungeachtet der möglichen Fehlerquellen, sollte der Test fehlschlagen.</p>
<p dir="ltr">Früher wurde bei der Quantität verschiedener Testarten oft das Modell der “Testing Pyramide” herangezogen, bei dem die Basis auf umfangreichen Unit-Tests lag, während nach oben hin weniger Integration- und End-to-End-Tests stattfanden. Heute spricht man jedoch vermehrt vom “Testing Pokal”. Bei diesem Modell stehen Integrationstests im Vordergrund, während die Anzahl an Unit-Tests verringert wird und End-to-End-Tests weiterhin oben angesiedelt sind. Dieser Wechsel zeigt den modernen Ansatz, in der Entwicklung auf umfassendere Tests zu bauen, die ein höheres Maß an Realitätsnähe bieten. Jede dieser drei Testmethoden findet trotzdem seinen Anwendungsbereich und ein gutes Zusammenspiel aus Unit-, Integration- und System-Testing hilft uns dabei, die Fehleranfälligkeit unserer Software stark zu verringern.</p>
<p dir="ltr"><img src="https://typedig.uber.space/assets/6f931982-2ad8-469d-9477-afd480fab0ab?width=1898&height=1017" alt="Testing Methods"></p>
<p dir="ltr"><em>Eine Testing-Gegenüberstellung des modernen Verfahrens "Testing-Pokal" vs. "Testing-Pyramide"</em></p>
<h2 dir="ltr">Durch Tests Softwarequalität verbessern</h2>
<p dir="ltr">Jetzt, da klar ist, dass die Fehleranfälligkeit unserer Software durch gut geschriebene Tests sinkt, gehen wir darauf ein, was das für die Arbeit von Entwicklern bedeutet. Denn Tests helfen nicht nur dabei Fehler zu vermeiden, sondern auch, besseren Code zu schreiben.</p>
<p dir="ltr">Anforderungsbasierte Tests haben zur Folge, dass der Code, der getestet wird, den vordefinierten Anforderungen auch gerecht wird. Und nicht nur das! Werden verschiedene Funktionalitäten beim Aufsetzen von Tests in kleinere Teile gegliedert, liegt es in der Natur der Sache, dass Programmierer letzten Endes auch ihren Code in Funktionen aufteilen, was die Lesbarkeit stark verbessert und potenzielle Refactorings, also das Überarbeiten von Software, vereinfacht. Durch das nun testgetriebene Entwicklung des eigenen Codes und dessen Dokumentation in Tests (Tests dienen Entwicklern auch als eine Art Dokumentation von gewünschtem Verhalten), schaffen wir es letzten endes auch, Duplikationen zu vermeiden, kontinuierliches Arbeiten an neuen Features zu vereinfachen und langfristig eine hohe Entwicklungsproduktivität zu garantieren.</p>
<h2 dir="ltr">Durch die richtigen Softwaretests langfristig Kosten sparen</h2>
<p dir="ltr">Eine solide Software zu entwickeln ist mit Kosten verbunden und viele Auftraggeber:innen sind dazu verleitet, auf das Testen von Code zu verzichten, da hier Kosten eingespart werden sollen. Zieht man jedoch in Betracht, dass 75 - 80% der Ressourcen für die Entwicklung eines Systems in die Instandhaltung und Erweiterung fließen², sollte man in diesem Fall nicht am falschen Ende sparen.</p>
<p dir="ltr">Ein Großteil der Arbeit an unserer Software beginnt nach dem ersten Release und diese Arbeit, effizient und kostengünstig zu gestalten, erfordert initial die zusätzlichen Kosten für Testing auf sich zu nehmen.</p>
<p dir="ltr">Du hast Fragen zu deinem aktuellen Softwareprojekt? Dann nimm gern Kontakt mit uns auf! Wir unterstützen Dich gerne bei deinem Vorhaben.</p>
<p dir="ltr">_ _ _</p>
<h6>¹ Frühauf, K., Ludewig, J., Sandmayr, H. (1988). Qualitätssicherung. In: Software-Projektmanagement und -Qualitätssicherung. Leitfäden der angewandten Informatik. Vieweg+Teubner Verlag, Wiesbaden. https://doi.org/10.1007/978-3-322-94671-3_5</h6>
<h6>² <strong id="docs-internal-guid-63ae9ff4-7fff-9ec3-f346-f38d2f8f83f1">Lientz, B., Swanson, E., & Tompkins, G. (1978). Characteristics of application software maintenance. Commun. ACM, 21, 466-471. https://doi.org/10.1145/359511.359522.</strong></h6>