Testing mit Feature Toggles

Wilhelm von Wiesel
Wilhelm von Wiesel 2020-11-21T16:48:03

Erinnern Sie sich noch an die „gute alte Zeit“?

Mir ist, als wäre es gestern , als der erste Personal Computer Einzug ins heimische Arbeitszimmer hielt. Eine Höllenmaschine, 386er, 2 MB RAM, 40 Mhz Taktfrequenz und 106MB Festplatte. Ich war etwa zehn Jahre alt und hatte die strikte Anweisung mich von dem Gerät fernzuhalten. Doch diese Anweisung war schnell vergessen, als meine Mutter für einen kurzen Einkauf das Haus verließ. Die Verlockung war einfach zu groß, das Gerät musste eingeschaltet werden.

Ratternd, nach einer Diskette im Laufwerk suchend, endete diese erste Begegnung zwischen mir und der Computerwelt mit einem Kurzschluss und einem rauchenden Netzteil. Mein erster Test an einem Computer: ein Desaster, welches meinem Vater am Abend schwer zu erklären war.

Für einen Softwareentwickler aus dieser Zeit muss die Welt im Vergleich zu heute noch in Ordnung gewesen sein. Kein Internet, keine Microservices, keine verteilte Architektur – ok – vielleicht hier und da ein Buffer Overflow, ein falsch adressierter Speicherbereich und natürlich immer zu wenig Systemressourcen.

Zum Glück müssen sich Entwickler von Webanwendungen in der heutigen Zeit darüber keine Gedanken mehr machen. Es ist alles da – Speicher, Rechenleistung und vernetzte Systeme sorgen für Daten im Überfluss.

Bedeutete das rauchende Netzteil meines 386ers damals das Ende meiner digitalen Welt, so wäre ein defektes Netzteil heute wohl kaum der Rede wert. Jeder von uns ist ausgerüstet mit zig mobilen Geräten, angefangen vom Auto bis hin zum Tablet. Intelligent vernetzt, überall verfügbar, nie offline.

Überträgt man diesen Zustand nun auf das Testing von neuen Funktionen unserer modernen Welt erkennt man schnell, dass ein klassischer „Ein/Aus-Testlauf“ – der vor 30 Jahren mein rauchendes Netzteil hätte verhindern können – heute wohl nicht mehr ausreichend ist. Eine ständig vernetzte Welt mit einer unerschöpflich großen Anzahl unterschiedlicher Endgeräte verlangt nach neuen Teststrategien.

Schauen wir uns diese Strategien anhand eines Beispiels an. Unsere Web-Entwickler haben die Aufgabe für eine Shop-Komponente eine neue, coole Suchfunktion zu implementieren. Dafür müssen unterschiedliche Komponenten angepasst und getestet werden. Natürlich entwickelt man so eine Funktion heute nicht mehr in einer einzelnen Anwendung. Für das Frontend muss eine Web-Komponente erstellt werden, für das Backend ein Such-Microservice, der die Produkte aus einer Produktdatenbank auslesen soll. Natürlich darf ein Cache dazwischen auch nicht fehlen.

Dem Entwicklerteam steht neben der Produktivumgebung auch eine Testumgebung zur Verfügung, auf der die grundlegende Integration der Komponenten durchgeführt wird. Hier haben wir aber schon eines der ersten häufigen Probleme: Die Dev-Umgebung entspricht nicht eins zu eins dem Aufbau der Produktivumgebung, die Suchkomponente ist aus Kostengründen nur einfach instanziiert und die Datenbank läuft nicht in einem Multi-AZ-Cluster.

Natürlich sollte ein Test in einer ersten Stufe trotz der nicht einhundertprozentig gespiegelten „Echt-Welt“-Umgebung genau unter diesen Bedingungen erfolgen, um die groben Fehler zu finden und diese vor dem Deployment auf die Live Umgebung zu fixen. Doch für einen „echten“ Test empfiehlt sich diese Umgebung nicht. Selbst wenn die Umgebung durch teures Geld gleichartig aufgebaut würde und die Daten gespiegelt wären, fehlt eine entscheidende Komponente: echte Kunden.

Durch den Einsatz von Feature Toggles kann dieses Lücke geschlossen werden. Anstelle Funktionen in einer Dev- oder Pre-Prod-Umgebung zu verproben, kann direkt in der Produktiv-Umgebung getestet werden. Hierzu wird die neue Suchfunktion im ersten Schritt in der Frontend-Komponente in eine getoggelte Funktion geschrieben, die mit einer bestimmten Bedingung verknüpft wird. Die Anwendung prüft nun also nicht mehr nur auf einen booleschen Zustand des Toggles, sondern übergibt ein zusätzliches Attribut, auf Basis dessen die Entscheidung getroffen wird, die Suchfunktion anzuzeigen oder eben nicht. Die Attribute können hierbei frei definiert werden, wobei sich Werte wie E-Mail-Adresse, Kunden-IDs oder auch die IP-Adresse der Test-Gruppenmitglieder (Beta Tester) zur Identifikation eignen. In diesem Zusammenhang spricht man auch von „User Targeting“.

Wurde der Test erfolgreich abgeschlossen, werden die Bedingungen am entsprechenden Toggle einfach entfernt, so dass die Funktion für alle Kunden sichtbar wird. Ein großer Vorteil des Feature Toggle Management Systems ist hierbei, dass sowohl das Hinzufügen von beliebigen Bedingungen als auch das Weglassen ohne Interaktion in die eigentliche Anwendung geschehen können. Soll ein Tester hinzugenommen oder entfernt werden, kann dies ohne Deployment der Applikation in Echtzeit erfolgen. Die Testgruppe muss sich damit auch nicht nur auf eine definierte Beta-Tester-Gruppe beschränken, denn über diese Technik wären auch die Konfiguration von Usern bestimmter Mailprovider oder einer bestimmten Geo-Region möglich.

Möchte man den Test nicht anhand eines spezifischen Userattributes entscheiden, sondern die Aufteilung der User in eine bekannte und unbekannte Gruppe dem Zufall überlassen, spricht man von A/B-Testing. Ziel dabei ist es, eine neue Funktion einer Kundengruppe bereits in einer sehr frühen Phase zur Verfügung zu stellen, um relativ schnell Feedback zu erhalten, bevor die Funktion flächendeckend ausgerollt wird. Teams können durch dieses frühe Feedback gezielt auf das Kundenverhalten eingehen und Anpassungen in der Entwicklung berücksichtigen. Gleichzeitig unterstützt diese Art des Vorgehens, eventuell auftretende Probleme im Infrastrukturbetrieb zu erkennen, bevor es zu spät ist. Sollte es zu größeren Problemen kommen, kann die Funktion auch jederzeit wieder ausgetoggelt werden.

Neben dem Rollout über kundenspezifische Merkmale bietet sich auch der prozentuale Rollout einer neuen Funktion an. Hierbei werden wie beim A/B-Test dem Benutzer nach einem Zufallsprinzip das neue Feature angezeigt oder nicht. Sollte die Aufteilung beim A/B-Test bei je 50% liegen, kann bei dieser Art der Konfiguration der prozentuale Anteil nach oben oder unten verschoben werden. Damit lassen sich auch für kleinere Usergruppen Funktionen freischalten, wobei die User anonym aus der gesamten Kundengruppe ausgewählt werden.

Fazit:

Die stetig wachsenden Anforderungen des Software LifeCycle erfordern auch im Testing zusätzliche Strategien. Der Einsatz von Feature Toggles eröffnet diesem Themenkomplex neue Wege und kann zu deutlich schnellerem Kundenfeedback für die Entwicklung gewünschter Funktionen führen. User Targeting ermöglicht es bestimmte Funktionen auch nur für spezifische Kundengruppen freizuschalten und bei Bedarf kurzfristig auf Störungen im Betrieb zu reagieren.