Kontextabhängiges Testen von Apps

Einleitung

Seit Einführung des ersten iPhones im Jahre 2007 ist die Popularität von Smartphones und der kurze Zeit später eingeführten Tablets extrem gestiegen. Die Geräte werden alltäglich genutzt und sind für eine zunehmend große Bevölkerungsschicht weder in Beruf noch in der Freizeit wegzudenken. Die geschäftliche Bedeutung wächst beständig [1]. Diese Entwicklung ist nur zum Teil darin begründet, dass Smartphones und Tablets eine wesentlich leistungsfähigere Hardware als Handys (oder sogenannte Feature Phones) besitzen. Parallel zur Hardware reiften die Werkzeuge zur Softwareentwicklung. Die Verfügbarkeit von Apps für eine unüberschaubare Vielfalt von Funktionen unterscheidet letztlich die modernen Geräte von einfachen Mobiltelefonen. Dabei gehen Apps sogar über das hinaus, was PC-Anwendungen bieten können, etwa indem sie Kamera oder Geolokation einbinden.

Die Erfahrungen in der App-Entwicklung halten sich bisher in Praxis und Wissenschaft in Grenzen. Zwar empfiehlt es sich, die erprobten Methoden des Softwareengineerings bei der Entwicklung von Apps einzusetzen, aber es sind Weiterentwicklungen notwendig. Bei der Umsetzung von App-Projekten betrifft dies vor allem die Gestaltung der grafischen Benutzerschnittstelle. Als besonders problematisch hat sich das Testen von Apps herausgestellt. Während Testen bereits bei PC- und Serveranwendungen alles andere als trivial ist [2], gibt es bei Apps einige zusätzliche Herausforderungen. Dabei besteht die Gefahr, den Mehrwert von Apps durch schlechte Softwarequalität aufs Spiel zu setzen und die Erwartungen der Nutzer zu enttäuschen. Gerade im geschäftlichen Umfeld ist dies inakzeptabel.

Die Schwierigkeiten beim Testen von Apps haben verschiedene Gründe. Apps werden nicht auf mobilen Endgeräten entwickelt; das Testen in Emulatoren liefert nicht notwendigerweise dieselben Resultate wie auf „echter“ Hardware. Zudem unterscheiden sich Endgeräte und herstellerangepasste Versionen mobiler Plattformen mitunter erheblich. Das Testen wird so sehr arbeitsaufwendig. Automatisierungen sind schwierig umzusetzen. Hinzu kommt, dass Apps häufig einen Technologiemix verwenden – etwa klassische Programmiersprachen kombiniert mit WebTechnologie. Der bedeutsamste Unterschied ist allerdings der Anwendungskontext. Einfaches Testen von Apps reicht nicht aus, da sie auch robust gegenüber Kontextwechsel sein müssen. Solche Wechsel, wie etwa eine Verschlechterung der Netzverfügbarkeit, sind hochgradig dynamisch.

In diesem Artikel stellen wir unseren Ansatz vor, mit Kontextwechseln beim Testen von Apps umzugehen. Das Konzept soll dabei helfen, die Effizienz zu steigern und eine höhere Qualität von Apps zu erreichen. Im nächsten Abschnitt führen wir zunächst in die Grundlagen ein, bevor wir anschließend unser Konzept erläutern. Es folgt eine Erörterung der bisherigen Erkenntnisse. Der vorliegende Artikel stellt eine Erweiterung des in [3] publizierten Artikels dar.

Kontext im Rahmen von Applikationen für mobile Endgeräte

Apps sind auf der einen Seite „normale“ Computerprogramme. Auf der anderen Seite unterliegen sie einer Reihe von besonderen Rahmenbedingungen. Sie müssen in vielen verschiedenen Situationen benutzbar sein und mit wechselnden Umgebungen zurechtkommen. Darüber hinaus müssen sie typischerweise robust gegenüber Unterbrechungen (zum Beispiel durch einen eingehenden Anruf) und sogar die plötzliche Beendigung sein. Letzteres ist auf die Unterschiede im Scheduling von Prozessen und im Speichermanagement gegenüber PCs zurückzuführen. Diese Beeinflussung durch den Kontext kann allerdings auch im Sinne der Nutzung sein, etwa wenn es um die Nutzung von Daten der Geolokation geht, oder der Zugriff auf Informationen der verfügbaren Bandbreite angepasst wird. Geschickt genutzt wird der Kontext daher zumindest in einigen Fällen eine Bereicherung.

Eine App existiert in einer ganzen Reihe von Kontexten: Der physische Kontext bezeichnet die physische Umgebung, in der sich das mobile Endgerät befindet. In der Regel ändert sie sich beständig, da die Nutzer Geräte mit sich führen. Der wichtigste Aspekt ist der Ort, der Kontextabhängiges auf verschiedene Arten und Weisen ermittelt werden kann. Nicht immer stehen alle diese Möglichkeiten zur Verfügung: In Gebäude ist zum Beispiel der GPS-Empfang häufig nicht verfügbar. Ist er verfügbar, könnte er eingeschränkt sein, was nur eine grobe Lokalisierung erlaubt. Der Standort wirkt sich auf weitere Kontextaspekte auf, etwa auf per Bluetooth oder Near Field Communication (NFC) ansprechbare Geräte sowie auf die Rückmeldung der verschiedenen Sensoren. Diese Vielzahl an physischen Kontexten ist für das Testen sehr bedeutsam, da Apps in hohem Maße von ihnen beeinflusst werden. Nicht nur die Wechsel selbst erschweren das Testen: Die verfügbaren Emulatoren können nur einen Teil der oben skizzierten Kontexte abbilden. Die nichtdeterministische Natur tatsächlichen Nutzungsverhaltens lässt sich nur bedingt in formalisierter Form wiedergeben. Werden Geräte zum Testen verwendet, ist die Simulation aller Kontexte daher keineswegs einfacher.

Der Kommunikationskontext hängt eng mit dem physischen Kontext zusammen. Der Standort determiniert die Netzwerkverbindung, die wiederum Verfügbarkeit, Latenz und Bandbreite bestimmt. Die mobile Internetverbindung ist zum Beispiel in Großstädten häufig stärker (UMTS, HSPA oder LTE) als in Dörfer und dort typischerweise „besser“ als in ländlichen Regionen (GPRS oder EDGE). An vielen Orten sind WLAN-Verbindungen verfügbar. Die Netzverbindung ist allerdings nicht statisch vom Standort abhängig. Bei Massenereignissen kann sie überlastet sein, Einflüsse wie Regen können zu Störungen führen. Apps müssen daher die dynamische Natur der Netzwerkverbindung berücksichtigen. Neben den Implikationen für die Softwareentwicklung ist beim Testen darauf zu achten, dass Apps tatsächlich robust sind und auf Änderungen der Verbindung oder Verbindungsqualität nicht mit Fehlverhalten reagieren. Zu prüfen ist insbesondere die Reaktion auf Jitter (Fluktuation beim Eintreffen von Daten), niedrige Datenübertragungsraten und alternierende Übertragungsraten – der Wechsel vom Telefonnetz auf WLAN erhöht zwar typischerweise die Dienstqualität, aber eine App muss diese Änderung „verkraften“ können. Problematisch beim Testen ist, dass keineswegs klar ist, welche Latenz, Dauer von Netzwerkunterbrechungen, Bandbreitenbeschränkungen usw. für eine bestimmte App hinnehmbar sind. Dies kann nur in Abhängigkeit der App selbst und der Gewohnheiten typischer Nutzer entschieden werden.

Der soziale Kontext setzt sich schließlich aus individuellen Besonderheiten der Nutzung zusammen. Viele mobile Geräte werden sowohl beruflich als auch privat genutzt. Selbst einzelne Apps – etwa solche zur Kommunikation – werden manchmal für beide Zwecke eingesetzt. Allerdings geschieht dies nur selten auf dieselbe Weise und mit denselben Anforderungen, etwa hinsichtlich der Sicherheit. Der Wechsel zwischen beruflichem und sozialem Kontext ist für die App typischerweise unmöglich festzustellen. Auch auf psychosoziale Gegebenheiten muss Rücksicht genommen werden. Eine App, die während der Bewegung oder sogar während eines Gesprächs genutzt wird, erhält zum Beispiel nur einen Bruchteil der Aufmerksamkeit des Nutzers. Schließlich haben auch Zeit, Wochentag und eventuell sogar das aktuelle Datum Einfluss auf die Nutzung, wie eine Studie gezeigt hat [4, p. 228]. Die Berücksichtigung technologisch bedingter Kontextwechsel ist für sich bereits problematisch, das Testen sozialer Kontexte der App-Nutzung allerdings kaum zu beherrschen.

Zu den drei Hauptkontexten kommen weitere Möglichkeiten der Kontextualisierung. Ein Beispiel sind die Software- und HardwareRahmenbedingungen, denen eine App unterliegt. Die Fragmentierung durch Hardware, die unterschiedliche Funktionen unterstützt, und ein Versionschaos bei mobilen Plattformen und Entwicklungsframeworks macht die Situation noch problematischer, als sie bereits im PC-Bereich ist. Es gibt zwar Fortschritte bezüglich der Standardisierung, aber Apps werden auch in Zukunft zum Beispiel eine Vielzahl von Auflösungen bedienen können müssen.

Blockbasiertes kontextabhängiges Testen

Unsere Idee zur Beherrschung der im vorherigen Abschnitt skizzierten Probleme ist das blockbasierte kontextabhängige Testen. Im Folgenden wird der Ansatz zunächst hergeleitet, dann im Detail vorgestellt, und schließlich anhand eines Beispiels illustriert.

Status quo und Grundlagen

Für konventionelle (Rich-Client-)Anwendungen und für Web-Applikationen existieren verschiedenste Frameworks für die Testautomatisierung. Für Apps ist die Unterstützung deutlich geringer ausgeprägt – insbesondere wenn es sich um das Testen nativer Apps und nicht von auf Web-Technologien basierenden Apps handelt. Während klassische Komponententests häufig mit denselben Werkzeugen wie auf dem PC möglich sind, fehlt die Abbildung des Kontextes. So ist es etwa nur bedingt möglich, Netzwerkschwankungen zu simulieren. Selbst wenn die Simulation externer Ereignisse und Rahmenbedingungen vom Emulator einer Plattform unterstützt wird, ist es schwierig, dies in automatisierte Tests einzubetten.

Zwei wesentliche Fragen stellen sich bezüglich kontextueller Aspekte des Testens von Apps:

  • Welches Niveau der Unterstützung von Kontextwechsel wird benötigt und ist zweckmäßig?
  • Wie muss eine Lösung zur Automatisierung aussehen, um Entwicklungsteams effektiv zu unterstützen?

Die einfachste Variante ist ein naiver Ansatz: Für jeden Testfall wird a priori durch den Entwickler festgelegt, in welchem Kontext er ausgeführt werden soll. Auf der Android-Plattform, d. h. in Java ließe sich dies etwa mithilfe von Annotationen oder durch die setUp()-Methode des JUnit-Frameworks umsetzen. Unabhängig von der technischen Umsetzung ist die Folge aber, dass Testfälle immer im Ganzen unter Beachtung des entsprechenden Kontexts ausgeführt werden. Dementsprechend können einzelne Quelltexteinheiten, die sich in verschiedenen Kontexten anders verhalten, mit diesem Ansatz gut automatisiert getestet werden. Die manuelle Interaktion mit Emulationswerkzeugen ist dann zur Durchführung von Tests in einem speziellen Kontext nicht mehr nötig.

Hinreichend ist diese Lösung in der Regel aber nicht. Viele kontextuelle Einflüsse sind nicht stabil, sondern zeichnen sich eben dadurch aus, dass sie sich dynamisch während der Applikationsnutzung ändern können. Wie bereits erörtert gilt dies insbesondere für die Eigenschaften der Netzwerkverbindung wie Latenz und Bandbreite, die bei Bewegung des Nutzers ständigen Änderungen unterlegen ist. Aus diesem Grund ist der naive, statische Ansatz wenig geeignet, wenn Kontextwechsel Einfluss haben können. Für die Nachahmung und Simulation von Geschäftsprozessen ist aber gerade dies erforderlich.

Die naive Reaktion hierauf wäre, eine Möglichkeit der Abbildung von Kontextwechseln zu schaffen, etwa durch Zugriff auf entsprechende Programmierschnittstellen (APIs). Somit ließen sich Kontextwechsel bei der Testfallausführung programmatisch einbeziehen. Der Ansatz bleibt dennoch statisch. Die Zahl der Testfälle wächst stark; gleichzeitig sinkt die Wartbarkeit wesentlich, sowohl durch die hohe Anzahl der Testfälle als auch durch die geringe Flexibilität des Ansatzes. Die Abbildung der Kontextwechsel als Teil der Testfälle bedeutet zudem mühsame manuelle Arbeit. Letztlich entstehen viele sehr ähnliche Testfälle, die sich nur im Code für den Kontextwechsel unterscheiden. Die Konsequenz ist, dass eine Multiplizierung der Testfälle vermieden und durch einen Ansatz ersetzt werden sollte, der Kontextwechsel automatisiert abbilden kann.

Wir bedienen uns der Modularisierung, um Testfälle zu ermöglichen, die ein Testen mit dynamisch wechselnden Kontexten unterstützen. Hierzu werden Testfälle in Blöcke unterteilt. Zwischen zwei Blöcken ist jeweils ein Kontextwechsel möglich. Somit können Testfälle vermieden werden, die sich nur durch die abgebildeten Kontextwechsel unterscheiden. Blöcke können beliebig wiederverwendet und mit verschiedenen Kontexten und Kontextwechseln kombiniert werden. Da Blöcke die Grundlage unseres Konzepts darstellen, haben wir es blockbasiertes kontextabhängiges Testen getauft.

Blöcke, Zusicherungen und Kontextwechsel

Ein Block ist das Grundgerüst jedes Testfalls. Er besteht aus Anweisungen zum Testen der App und entsprechenden Zusicherungen (Assertions). Anweisungen werden genutzt, um Interaktion des Anwenders mit einer App zu imitieren. Diese Interaktionen werden programmatisch durch die Verkettung entsprechender Methoden wie zum Beispiel gebeTextEin(), klickeButton() oder wischeNachLinks() entwickelt. Mehrere Anweisungen – ggf. unterteilt in verschiedene Blöcke – können einen Anwendungsfall (Use Case) der App wiederspiegeln. Zusicherungen werden genutzt, um sicherzustellen, dass nach gegebenen Interaktionen das gewünschte Verhalten eintritt. Sowohl Testanweisungen als auch Zusicherungen werden in weit verbreiteten Testframeworks wie zum Beispiel JUnit oder dem Android-Testframework verwendet.

Grundidee unseres Konzepts ist es, Blöcke aus Testfällen (wie zum Beispiel der „Basisvariante“ – ohne Kontextwechsel) abzuleiten und damit eine Struktur zu schaffen, die es ermöglicht, viele verschiedene kontextabhängige Testfälle zu generieren. Ein Testfall kann in beliebig viele Blöcke zerlegt werden, abhängig davon, wie häufig Kontextänderungen simuliert werden sollen. Um den Anwendungsfall nicht zu verändern und nur die Kontexte zu variieren, müssen Blöcke in eine Reihenfolge gebracht und später in genau dieser ausgeführt werden.

Ein Block ist in Bezug auf Kontextwechsel atomar; er bildet Funktionalität ab, die immer komplett innerhalb eines gewissen Kontexts ausgeführt wird. Zwischen zwei Blöcken ist es möglich, Kontextwechsel auszuführen. Um verschiedene Szenarien (in Bezug auf Kontextwechsel) zu testen, müssen die Testanweisungen nicht wiederholt werden. Lediglich die Reihenfolge bzw. das Stattfinden von Kontextwechseln muss unterschiedlich konfiguriert werden. Die Blöcke von Testanweisungen sind insofern modular und werden wiederverwendet. In Kombination mit einem Generator, der automatisch Testfälle aus Blöcken mit unterschiedlichen Kontextwechseln erstellt, wird das Konzept am meisten Vorteile liefern. Denn neben der Vermeidung von Komplexität bietet die Einsparung manueller Arbeit den größten Effizienzgewinn. Sowohl die Zeitpunkte als auch die Reihenfolge der verschiedenen Kontextwechsel können in beliebig vielen Kombinationen variiert werden, ohne dass hohe Aufwände für die Erstellung einzelner konkreter Testfälle entstehen. Der manuell Aufwand wird reduziert und das Auftreten von redundanten Testanweisungen minimiert. Darüber hinaus ergibt sich eine klare Trennung von Verantwortlichkeiten: Der Testfall (abgebildet in Blöcken) adressiert die Funktionalität einer App und wird wiederverwendet, um das gewünschte Verhalten in verschiedenen Kontexten zu testen. Insbesondere bei schwierig zu testenden Apps oder komplexen Kontextabhängigkeiten wird die gemeinsame Entwicklung von Testfällen etwa durch einen Tester und einen Domänenexperten vereinfacht.

Die oben skizzierte Idee von Blöcken, zwischen denen Kontextwechsel stattfinden können und aus denen Testfälle generiert werden, ist allerdings nur dann sinnvoll nutzbar, wenn die zu testenden App in wechselnden Kontexten analog funktionieren soll. Oft ist gerade dies aber nicht der Fall. Eine App kann beispielsweise in einem Kontext „ohne Internetverbindung“ ein anderes gewünschtes Verhalten aufweisen als mit Verbindung zum Internet. Wenn Apps solch kontextabhängiges Verhalten haben und der Kontext während der Testausführung geändert wird, reichen einfache Zusicherungen, die statisch in Blöcken enthalten sind, nicht mehr aus, um das gewünschte Verhalten zu überprüfen.

Um kontextabhängiges Verhalten von Apps zu testen, müssen Blöcke feiner geschnitten werden. Da der Assertion-Teil eines Blocks potenziell vom Kontext abhängt, in dem der Test ausgeführt wird, muss dieser separiert werden. Zu den Blöcken, die jetzt nur noch die Testanweisungen enthalten, muss zusätzlich mindestens eine Zusicherung definiert werden. Für jeden Kontext, in dem die App ein unterschiedliches Verhalten aufweisen soll, muss eine weitere Zusicherung hinzugefügt werden, die genau dieses prüft.

In Abbildung 1 sind die Bausteine des Konzepts visualisiert. Die Struktur eines Testfalls wird durch eine geordnete Liste von Blöcken gebildet. Zu jedem Block gibt es mindestens eine „Standard Assertion“ (d. h. die grundlegende Zusicherung). Da das erwartete Ergebnis eines Blockes aufgrund von Kontextabhängigkeiten verschieden sein kann, können mehrere Zusicherungen (dargestellt als Achtecke) pro Block existieren. Zwischen den Blöcken eines Testfalls kann der Kontext variieren. Welche Zusicherung zur Überprüfung des erwarteten Verhaltens herangezogen wird, hängt davon ab, in welchem Kontext der zugehörige Block ausgeführt wurde. Im folgenden Abschnitt wird das Konzept des blockbasierten kontextabhängigen Testens anhand eines Beispiels verdeutlicht.

Beispiel: kontextabhängige Testfallausführung

Aus den in Abbildung 1 gezeigten Bausteinen können mehrere Testfälle generiert werden. Abbildung 2 zeigt einen der möglichen Testfälle, die aus den vorher genannten Elementen generiert werden könnten.

Der Startpunkt der Testfallausführung ist als leere Menge dargestellt. Zu Beginn des Testfalls wird die App in den Initialkontext (Kontext 1) versetzt. Nachdem die Testanweisungen aus Block 1 abgeschlossen sind, wird eine zum aktuell gültigen Kontext passende Zusicherung gesucht. Für Kontext 1 und Block 1 gibt es eine kontextabhängige Zusicherung (Assertion A1.1), wie in Abbildung 1 dargestellt. Falls die zu testende App ein Verhalten aufweist wie von der Zusicherung gefordert, wird die Testfallausführung fortgesetzt, andernfalls hat der Testfall einen Fehler aufgedeckt. Offenbar wurde ein kontextabhängiges Fehlverhalten beobachtet.

Zwischen Block 1 und Block 2 findet ein Kontextwechsel statt, d. h. die App wird in Kontext 2 versetzt und verbleibt in diesem für den Rest der Testfallausführung. Ähnlich wie Block 1 wird auch Block 2 zusammen mit einer kontextabhängigen Zusicherung ausgeführt. Bei Block 3 ist dies anders: Wie in Abbildung 1 zu sehen ist, hat Block 3 nur eine grundlegende Zusicherung. Das Vorkommen von nur einer Zusicherung lässt darauf schließen, dass das erwartete Verhalten der App an dieser Stelle invariant zwischen allen Kontexten ist. Deshalb wird nur eine Zusicherung benötigt, die eben dieses Verhalten überprüft. Schlussendlich wird Block 4 zusammen mit einer kontextabhängigen Zusicherung ausgeführt und der Testfall beendet.

Wird bedacht, dass zwischen jedem Block der Kontext potenziell wechselbar ist, wird klar, dass es für einen Testfall sehr viele verschiedene Ausführungspfade geben kann. Darüber hinaus ist es wahrscheinlich, dass – anders als in diesem Beispiel – Apps in der Praxis in mehr als zwei Kontexten getestet werden müssen. Das Hinzunehmen von weiteren Kontexten, in denen sich die zu testende App jeweils unterschiedlich verhalten kann, erhöht die Anzahl der möglichen Ausführungspfade eines Testfalls drastisch, da die Möglichkeiten multiplikativ verknüpft sind. Durch das Konzept des blockbasierten kontextabhängigen Testens wird die mitunter exponentiell wachsende Anzahl von Testfällen reduziert, die beim herkömmlichen Testen

durch das Betrachten weiterer Kontexte hinzukommen würden. Die Struktur eines Tests im blockbasierten kontextabhängigen Testen bleibt stabil, wie die Liste der Blöcke in Abbildung 1 zeigt. Lediglich der Kontext verändert sich und somit werden gegebenenfalls unterschiedliche Zusicherungen zum Prüfen der erwarteten Funktionalität der zu testenden App genutzt.

Diskussion

Nutzen und Anwendungsmöglichkeiten

Zu dem vorgestellten Konzept des blockbasierten kontextabhängigen Testens haben wir eine Proof-of-Concept-Implementierung erstellt. Die Grundlage bilden das Android-Testframework, JUnit und Robotium, ein Framework zum komfortablen Schreiben von Testfällen für Android-Apps. Anschließend haben wir das entwickelte Test-Tool genutzt, um beispielhaft Apps zu testen. Es hat sich gezeigt, dass es mit Hilfe des Tools möglich ist, automatisch viele verschiedene kontextabhängige Testfälle aus einer Teststruktur (wie oben beschrieben) zu erstellen. Dies vereinfacht das Testen von Apps unter verschiedenen kontextuellen Bedingungen. Die entwickelte Lösung nutzt verschiedene Generatoren, um automatisch Testfälle aus einer gegebenen Liste von Blöcken zu erzeugen. Ein Generator generiert beispielsweise eine Anweisung zum Kontextwechsel nach jedem Block, wobei zwischen zwei Kontexten alterniert wird. Ein weiterer generiert so viele Testfälle, wie es Blöcke gibt, und erzeugt eine Anweisung zum Kontextwechsel pro Testfall, wobei der Block, nachdem der Kontextwechsel stattfindet, variiert wird. Ein spezieller Testrunner ist dann in der Lage, die App in den jeweils gewünschten Kontext zu setzen und somit kontextabhängige Testfälle auszuführen. Bei der Entwicklung haben wir uns auf den Kommunikationskontext von Apps sowie das Android-Betriebssystem beschränkt. Die Lösung auf Betriebssysteme anderer Plattformen zu übertragen sowie weitere Kontexte hinzuzunehmen, sollte einfach möglich sein, denn das Konzept bleibt gleich, die Werkzeuge ähnlich.

Die Grundidee, viele Testfälle aus einer statischen Teststruktur zu erzeugen und dabei den Kontext zu wechseln, reduziert manuellen Aufwand zum Erstellen und Ausführen von kontextabhängigen Testfällen. Da die Kontextwechsel automatisiert und in unterschiedlichen Reihenfolgen zwischen den Blöcken stattfinden, ermöglicht es unsere Lösung, Fehler in Bereichen von Apps zu finden, in denen sie normalerweise nicht erwartet worden wären. Da Tests im Feld (d. h. in den verschiedenen Kontexten) typischerweise viel Zeit und ein hohes Testbudget erfordern, werden diese oft vernachlässigt. Unser Konzept bietet eine kostengünstige Alternative, zumindest einen Teil der Tests unter Laborbedingungen durchzuführen. Fehler werden so vor Auslieferung entdeckt, was die Kosten für die Behebung deutlich senken kann. Dennoch wird es kein Allheilmittel in Bezug auf Kontextprobleme bei der Entwicklung und dem Testen von Apps sein. Vielmehr ist es als unterstützendes Hilfsmittel zu sehen, das genutzt werden kann, um Teile von Apps zu testen, die häufigen Kontextwechseln begegnen und entsprechend gut damit umgehen müssen.

Ausbaupotenzial und offene Fragen

Unsere Arbeit stellt einen ersten Schritt dar, Kontext im Rahmen des Testens von Apps zu berücksichtigen. Als Ergebnis ergeben sich daher neue Fragestellungen. Auch zeichnet sich bereits Ausbaupotenzial ab.

Eine wesentliche Frage im Rahmen kontextabhängigen Testens ist, wie die entsprechenden Kontexte bei Testausführung simuliert werden können. Denn während die Kontextwechsel sehr vereinfacht werden konnten, hat unser Ansatz keinen direkten Einfluss auf die Kontexte an sich. Es handelt sich daher um keine konzeptuelle Einschränkung, wohl aber um eine sich ergebende Herausforderung. Sie betrifft nicht nur die technische Dimension. Werkzeuge, die Netzwerkbandbreite und -latenz simulieren, existieren bereits seit längerem oder können mit überschaubarem Aufwand neu implementiert werden. Wie allerdings Wechsel des sozialen Kontexts abgedeckt werden können, bleibt als Forschungsfrage offen.

Eine mögliche Erweiterung unseres Ansatzes wäre die Einbeziehung von Geschäftsprozessen. Derzeit werden Blöcke immer linear abgearbeitet. Allerdings wäre es möglich, dass Kontextwechsel zwischen Blöcken eine abweichende Verarbeitungsreihenfolge bedingen. So könnte eine App etwa bei fehlender Netzwerkanbindung nicht komplett den Dienst versagen, sondern einen angepassten Funktionsumfang anbieten. Eine Lösung wäre, Blöcke als Knoten eines Graphen aufzufassen; die zu „beschreitenden“ Kanten könnten bei Bedarf abhängig vom Ergebnis des Kontextwechsels gemacht werden. Unser Prototyp bietet eine einfache Abdeckung solcher Fälle, die aber im Rahmen einer Erweiterung deutlich ausgebaut werden könnte.

Unser prototypisches Werkzeug kann bereits genutzt werden, um Apps auf ihre Robustheit hin zu überprüfen. Insbesondere für Apps ist ein hohes Maß an Robustheit bedeutsam, da sie sehr einfach zu bedienen sein sollen und der typische Anwender über wenig technisches Wissen verfügt. Sinnvoll wäre daher, ein Rahmenwerk zu erstellen, das prüft, wie robust Apps auf Kontextwechsel reagieren. Im Sinne unseres Ansatzes ist diese Überprüfung ein Nebenprodukt. Ein entsprechender Rahmen könnte nicht ausschließlich ein höheres Maß an Automatisierung bieten. Vielmehr sollten Mitarbeiter der Qualitätssicherung dabei unterstützt werden, Szenarien, in denen Robustheit gefordert wird, abzudecken. Nötig wäre daher neben der Implementierung eines Frameworks auch die Erarbeitung von Praktiken zur Aufdeckung wenig robusten und damit mittelbar wenig benutzerfreundlichen Verhaltens. Neben den Kontextwechseln im Sinne unseres Ansatzes kommt hier noch ein weiterer Gedanke hinzu. Unterschiedliche Nutzergewohnheiten sollten wenn möglich berücksichtigt werden. Im Idealfall werden Apps sogar so entwickelt, dass sie sich an den Nutzer anpassen. Beispiele hierfür sind zum Beispiel Werkzeuge für das schnellere „Tippen“ mit der Touchscreen-Tastatur, die das Nutzerverhalten analysieren und sich daraufhin anpassen. Die Effektivität solcher Maßnahmen ließe sich hervorragend mit der Robustheitsprüfung kombinieren.

Neben der technologischen Weiterentwicklung wäre es sinnvoll, die Benutzerunterstützung auszubauen. Um eine Integration von automatischer und manueller Testfallerzeugung zu bieten, wäre ein grafischer Editor hilfreich. Blöcke ließen sich so sehr einfach definieren, Testfälle würden im zweiten Schritt per Dragand-drop erstellt. Auf diese Weise ließen sich auch die oben angesprochenen nichtlinearen Workflows relativ mühelos festlegen. Neben der Erstellung würde so auch die Verwaltung von Testfällen vereinfacht, etwa indem sie nach Geschäftsprozessen und bei Bedarf zusätzlich nach Arten der Kontextwechsel gruppiert werden könnten. Möglicherweise ließe sich sogar eine Integration mit Modellierungswerkzeugen für Geschäftsprozesse erreichen, so dass die Brücke zwischen betrieblicher und informationstechnischer Welt geschlagen werden könnte. Ein Teil unserer Ergebnisse wird in der Literatur bestätigt. Im White Paper wird etwa empfohlen, Emulatoren und per Fernzugriff verfügbare echte Geräte zum Testen zu verwenden – wenn möglich automatisiert. Die auf diese Weise abgedeckte Heterogenität der Geräte und die sich daraus ergebenden Schwierigkeiten werden zumindest zum Teil durch unseren Ansatz adressiert, auch wenn Probleme beim Testen durch Kontextwechsel nicht explizit angesprochen werden. Insgesamt kann die Literatur bisher nur wenige handfeste Lösungen liefern. Die Empfehlungen in oben genanntem Dokument bleiben sehr allgemein.

Um den Schwierigkeiten durch die Fragmentierung der Endgeräte und auch sozialen Kontextwechseln Herr zu werden, sind Ideen wie Crowdtesting beachtenswert. Hierbei werden Testaktivitäten abgegeben und im Falle von Testbirds nicht nur durch Tester, sondern durch einen großen Pool an registrierten Endanwendern mit verschiedensten Geräten und Konfiguration bearbeitet. Ob solche Lösungen allerdings effektiv und vor allem finanziell sinnvoll sind, wird sich noch zeigen müssen.

Schlussbetrachtungen

Im vorliegenden Artikel haben wir unser Konzept zum blockbasierten kontextabhängigen Testen von Apps beschrieben. Der Beitrag liegt insbesondere in der Beschreibung, wie das automatische Testen von Apps in einer von Kontextwechseln geprägten Umgebung realisiert werden kann. Anhand unserer Proof-of-Concept-Implementierung und eines Beispiels haben wir gezeigt, dass der Ansatz dabei helfen kann, kontextabhängige Fehler in Apps aufzudecken. Neben den Vorzügen des Ansatzes darf allerdings nicht unerwähnt bleiben, dass eine Weiterentwicklung nötig ist und Fragen offen blieben.

Auch wenn unsere prototypische Implementierung als quelloffene Software zur Verfügung steht, gehen wir davon aus, dass ähnliche Werkzeuge durch Dritte erstellt werden. Wir würden dies ausdrücklich begrüßen, da nur durch weitere Forschungsarbeit und das Sammeln von Erfahrungen ein Ausbau und damit ein weiterer Effizienzgewinn möglich sein werden. Insbesondere müssen die aufgezeigten Einschränkungen und Probleme adressiert werden. Festzuhalten ist ferner, dass Kontextabhängigkeit nicht die einzige Schwierigkeit beim Testen von Apps ist. Generell sind noch viele Schwierigkeiten zu lösen, um qualitativ hochwertige Apps zu erhalten, ohne dass der Testaufwand ausufert. Wird allerdings bedacht, welchen Nutzen mobile Endgeräte für viele Menschen mittlerweile stiften, ist diese Forschungsarbeit und ihre praktische Evaluation äußerst lohnenswert. Abgesehen davon handelt es sich um eine spannende Herausforderung, die Erkenntnisse aus der Vergangenheit mit Innovationen verbindet. Wir bleiben dem Thema treu und planen für die Zukunft, weitere Ansätze vorzustellen. Wir sind optimistisch, dass andere es uns gleich tun und ein schneller Fortschritt beobachtet werden kann.

Literatur

[1] Heitkötter, H., Majchrzak, T. A., Wolffgang, U. and Kuchen, H.: Business Apps: Grundlagen und Status quo. Working Papers des Förderkreis der Angewandten Informatik an der Westfälischen Wilhelms-Universität Münster e.V., Number 4, Münster (2012)
[2] Majchrzak, T. A. (2012). Improving Software Testing: Technical and Organizational Developments. Springer Verlag.
[3] Schulte, M. and Majchrzak, T. A.: ContextDependent Testing of Apps. In: Testing Experience, 19, September, Díaz & Hilterscheid Unternehmensberatung GmbH (2012)
[4] Verkasalo, H. (2011). Propensity to Use Smartphone Applications. In: Proceedings of the Fifth International Conference on Mobile Ubiquitous Computing, Systems, Services and Technologies, pp. 223–229.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Kategorien

Recent Posts