Wie teste ich flexibel und souverän?

Wie kann man die Qualiät von IT-Anwendungen zuverlässig und flexibel testen, wenn sich das Marktumfeld laufend verändert und die Markteinführung immer schneller erfolgt?

In diesem Interview beschreiben Jean François Poilprêt (JP), Senior Manager, und Benjamin Audren (BA), Testing Consultant, vom Testteam der ELCA Informatique SA Lausanne, wie automatisierte Tests und fortlaufende Integration eine kontinuierliche Verbesserung der Softwarequalität bei kurzen Entwicklungszyklen möglich machen.

Wie kann man in Zeiten schneller Markteinführungen die Qualität von IT-Anwendungen sicherstellen?

JP - Das ist heute eine der grössten Herausforderungen im IT-Geschäft! Es stimmt: Was unsere Entwicklung neuer oder die Verbesserung bestehender Anwendungen betrifft, sind die Erwartungen unserer Kunden enorm gestiegen. Vor zehn Jahren wurde Softwareentwicklung ganz anders wahrgenommen. Heute wollen Kunden in die Gestaltung des Endprodukts mit einbezogen werden und sie erwarten schnelle Ergebnisse und kurze Lieferzeiten, damit die Endnutzer die Vorzüge so schnell wie möglich geniessen können. Diese Erwartungen haben neuen Methoden im Softwareentwicklungszyklus den Boden bereitet, insbesondere allen "agilen" Verfahren (Extreme Programming, Scrum). ELCA hat diesen Trend frühzeitig aufgegriffen und ein eigenes Verfahren namens AgileIT entwickelt, um die neuen Erwartungen ihrer Kunden zu erfüllen. Agile Methodologien setzen kurze Entwicklungszyklen, sogenannte Sprints, voraus. Der Zweck eines Sprints ist es, in der Lage zu sein, ein lauffähiges System mit allen dazu ausgewählten Features zu liefern.

Das hört sich so an, als wäre es schwer, in so kurzer Zeit zu liefern. Wie schaffen Sie es, die Qualität dabei nicht aus den Augen zu verlieren?

JP - Aufgrund der kurzen Entwicklungszeit wurde das Projektteam neu organisiert und die Testverfahren effizienter gestaltet. Tatsächlich ist ein Sprint immer auf einen bestimmten Funktionsumfang fokussiert, auch als "User Stories" bekannt, muss aber am Ende ein lauffähiges System hervorbringen, das auch alle Funktionen aus vorherigen Sprints beinhaltet. Einerseits ist das Regressionsrisiko – also das Risiko, dass eine Funktion, die zuvor korrekt gearbeitet hat, nicht mehr funktioniert – sehr hoch, wenn man keine ausreichenden Tests durchführt; die Funktionen immer und immer wieder bei jedem Sprint zu testen, kann andererseits teuer und zeitaufwendig sein. Hier schafft die Automatisierung Abhilfe: Automatisierte Tests sind zwar teurer als manuelle, wenn man eine Funktion nur einmal testet. Bei mehrfacher Ausführung lohnt sich die Investition aber sehr schnell, da weitere Testrunden keine neuen Kosten verursachen und Aktualisierungen schneller ausgeliefert werden können.

 

Automatisierte Testverfahren erscheinen sinnvoll, aber wie stellen Sie sicher, dass die tägliche Qualität der entwickelten Software nicht leidet?

JP - Um die Effizienz von Sprints zu gewährleisten, sind agile Prozesse darauf ausgelegt, Fehler so schnell wie möglich zu finden und zu beseitigen. Möglich wird das durch kontinuierliche Integration (Continuous Integration), wobei Teammitglieder nach der Entwicklung einer Funktion dessen Quellcode in den Quellcode des Projekts einpflegen (indem sie diesen im sogenannten "Source Repository" ablegen). Danach kommt eine spezielle Maschine zum Einsatz, die 1) den neuesten Quellcode für das gesamte Projekt einholt, 2) aus diesem Quellcode ein Programm erstellt, 3) dieses Programm in einem speziellen Testumfeld ausführt und 4) alle automatisierten Tests an dem neu entwickelten Programm durchführt. Anschliessend erhält das Projektteam die Ergebnisse, wobei eine mögliche  Fehlerbehebung im Vordergrund steht: Kam es während der kontinuierlichen Integration zu Fehlern, muss der verantwortliche Entwickler (also derjenige, der als letzter einen Quellcode abgelegt hat – da dieser sozusagen "das Konstrukt zerschlagen" hat ("has broken the build")) diesen Fehler so schnell wie möglich beheben. Dieses Verfahren stellt sicher, dass der aktuellste Quellcode immer ein lauffähiges Programm hervorbringt. Zudem ist es einfacher, einen Fehler zu beheben, sobald er auftritt. Eine spätere Korrektur, insbesondere wenn der Fehler erst entdeckt wird, während das Programm in der Produktion ist, ist viel schwieriger durchzuführen.

 

Ist es möglich, sämtliche Testverfahren für ein bestimmtes Programm zu automatisieren?

BA - Die Versuchung, eine solche Frage mit "Ja" zu beantworten, ist immer eher gross, vor allem, wenn man mit Teams arbeitet, die extrem hoher Arbeitsbelastung durch manuelle Tests ausgesetzt sind und nach einer perfekten Lösung für ihre Probleme suchen. In der Praxis sollte man zwischen der Steuerung einer Anwendung und dem Test einer Anwendung unterscheiden. In den meisten Fällen ist es möglich, ein Programm in alle möglichen Richtungen zu steuern und zu simulieren, wie der Nutzer mit dem Programm umgehen würde. Je nachdem, wie komplex die Anwendung ist und wie sie mit anderen Programmen auf dem Rechner interagieren kann, kann es sehr aufwendig sein, den Autopiloten zu programmieren und instand zu halten. Das Testen beschränkt sich nicht allein auf die Steuerung der Anwendung: Es geht darum, ihren aktuellen Zustand zu verstehen und herauszufinden, inwieweit sie nicht richtig funktioniert. Kontrollen sind ein wichtiger Teil dieses Prozesses und können leicht automatisiert werden, da es naturgemäss um eindeutige Eigenschaften geht (diese Zahlen sollten gleich sein, dieser Nutzer sollte nicht die Rechte haben, das zu tun usw. ...). Kontrollen verifizieren lediglich die aktuellen Erwartungen für bestimmte Spezifikationen, garantieren jedoch nicht, dass das System tatsächlich funktioniert. Testverfahren sollten auch tiefergehend ergründen, Fragen stellen, das System untersuchen und können auch einmal ergebnisoffen ausgehen. Das sogenannte «explorative Testen» ist im Wesentlichen eine intellektuelle Aufgabe, bei der Automatisierungsinstrumente helfen können – genauso, wie ein gut funktionierendes integriertes Entwicklungsumfeld Programmierer unterstützen kann, indem es einige der arbeitsintensiven Schritte übernimmt. Wenn man die repetitiven und fehleranfälligen Aufgaben automatisiert, kann ein agiles Team das Wissen seiner Entwickler um die Anwendung besser nutzen und eine bessere Qualität erreichen. 

Wie entscheiden Sie, welche Aufgaben automatisiert werden können oder sollten?

JP - Das ist die Millionenfrage! Das ist nicht einfach, weil jeder gerne 100 Prozent aller Tests automatisieren würde, aber wie bereits gesagt, ist das unmöglich. Zusätzlich sind auch unsere Zeit- und Geldbudgets begrenzt, so dass wir nicht so viel automatisieren können, wie wir gerne würden. Wir orientieren uns bei der Entscheidung meistens am Risiko und am Wert einer Anwendung und kombinieren das mit einer einfachen Rentabilitätsanalyse: Dafür ordnen wir zuerst alle Funktionen nach ihrem Wert, wir überlegen also, welche Funktionen dem Nutzer in den meisten Fällen den grössten Mehrwert bieten. In diese Bewertung fliesst auch mit ein, wie häufig eine Funktion genutzt wird. Die Funktionsprioriät wird dann moduliert, wobei das Risiko für den Kunden durch Funktionsfehler und mögliche verfügbare Behelfslösungen, die eingesetzt werden, wenn eine Funktion nicht genutzt werden kann, ausschlaggebend sind (beispielsweise berechnen wir Tagesverluste, die durch Funktionsfehler entstehen). Manchmal berücksichtigen wir auch die Wahrscheinlichkeit, eine Funktion langfristig arbeitsunfähig zu machen (Regression); diese Wahrscheinlichkeit hängt von der Komplexität des Geschäftsmodells und des Quellcodes ab, aber auch die Anzahl der Funktionen, die denselben Quellcode nutzen, spielt eine Rolle. Zu guter Letzt veranschlagen wir auch die Komplexität einer Automatisierung des Testverfahrens (daher der dafür notwendige Aufwand) im Vergleich zu einer manuellen Testausführung. Es ist nicht immer einfach, klare Regeln aufzustellen, wann ein Test automatisiert werden soll und wann nicht. Tatsächlich geben wir manchmal nur Rahmenrichtlinien vor. In einem Scrum-basierten Projekt können wir die Entscheidung kollektiv treffen, wenn eine Funktion programmiert wird bzw. unmittelbar zuvor während des Scrum-"Sprint Planning 1"-Meetings und in Absprache mit dem Besitzer des Produkts.

 

Wie nachhaltig sind Teststrategien für fortschreitende Anwendungen?

BA - Wie bereits erwähnt, muss man aufgrund der Mühe und des Aufwands genau überlegen, welche Szenarien man automatisch prüfen möchte. Es wäre besorgniserregend, wenn dieser Automatisierungsaufwand jedes Mal aufs Neue betrieben werden müsste, sobald die Anwendung in ihrer normalen Entwicklung fortschreitet. In diesem Fall wäre es unmöglich, mit einer schnell fortschreitenden Software Schritt zu halten. Glücklicherweise kommt hier die Architektur der Automatisierung ins Spiel. Durch die Verwendung mehrerer Ebenen kann man möglicherweise instabile technische Teile der High-Level-Beschreibung von Testszenarios isolieren. Dadurch wird die Instandhaltung von Testverfahren handhabbar, und die Szenarien werden zu einer klaren und deskriptiven Dokumentation der Funktionsweisen. Der Vorteil dieser stabilen, automatisierten Szenarien, die sich wie eine Dokumentation lesen, besteht darin, dass sie nicht anfällig für Refactoring oder grosse Veränderungen in der grafischen Benutzeroberfläche sind. Da sie die Funktionalitäten für den Endnutzer prüfen, gewährleisten sie die Nicht-Regression und geben dem Entwicklungsteam das Vertrauen, dass Veränderungen im Hintergrund den Vordergrund nicht beeinflussen. Heute ist ein tiefgreifendes Refactoring der Anwendung zur Anpassung an neue Kundenbedürfnisse eine häufige Herausforderung, die sowohl die Neugestaltung der Basismodelle zur Performanceverbesserung, als auch die Einführung von Microservices zur Skalierung des Teams betreffen kann, die Auslagerungen von Teilen der Anwendung oder die Nutzung externer Datenquellen. Ein robuster und automatisierter Teil des Testverfahrens schafft ein Qualitätssicherungssystem, das Ressourcen freisetzt, die diese Ziele mit Agilität und Zuversicht erreichen können.