Nichts anbrennen lassen

Mit Googles Firebase Apps auf Herz und Nieren testen
Keine Kommentare

Google bietet mit Firebase einen Onlinedienst an, der von Nokias mittlerweile legendärem RDA inspiriert wurde. Die dahinterstehende Idee ist einfach: Ein über das Internet ansprechbares Testlabor hält eine Vielzahl von Geräten vor, die mit der vom Entwickler angelegten Software ausgestattet werden.

Zu Zeiten von Palm OS hatten kleine und große Entwickler einen ganzen Stapel Testgeräte – der Haufen der in Bratislava ansässigen Resco war geradezu episch. Heute ist diese Vorgehensweise nicht wirklich zielführend: Erstens ist die Anzahl der verfügbaren Geräte geradezu erschlagend, zweitens müssen Sie sich als Entwickler zudem mit einer Vielzahl verschiedener Versionen herumschlagen. Wer einige Male verschiedene ROMs auf ein Testgerät spielt, lernt bald mehrsprachiges Fluchen. Die beste Lösung für das Problem ist Spezialisierung, bei der Firebase helfen kann.

Der wichtigste Unterschied zwischen RDA und Firebase ist, dass Firebase ferngesteuert abläuft – der Entwickler muss also nicht, wie einst bei Nokias Plattform, auf den Geräten herumklicken und sich mit langsamer Bildschirmaktualisierung per VNC herumärgern. Was dies in der Praxis bedeutet und wie Sie die Vorteile von Firebase in Anspruch nehmen können, wollen wir in den folgenden Schritten näher analysieren.

Gleich ran

Als erste Aufgabe wollen wir die Firebase-Konsole öffnen. Sie dient als Schnittstelle zwischen dem Entwickler und den diversen im Google Backend angelegten Services. Klicken Sie auf die Option EXPLORE A DEMO PROJECT und nicken Sie die Lizenzanfrage ab. Wir wollen in den folgenden Schritten auf von Google bereitgestellte Programmbeispiele setzen, weil wir uns hier auf die eigentliche Vorstellung der Testverfahren beschränken wollen und lange Diskussionen der Testharnische nicht zielführend sind.

Nach dem erstmaligen Einblenden finden Sie sich in der Demoapplikation MechaHamster wieder: Klicken Sie auf die Combobox, um stattdessen in das Programm Flood It! zu wechseln. Am Bildschirm sehen Sie sodann eine Liste von als Matrix bezeichneten Testläufen, die die eigentlichen Ergebnisse der Analyseprozesse zutage fördern. Das Anklicken einer der Testläufe bietet weitere Informationen über die jeweiligen Ergebnisse – im Fall des von Google bereitgestellten Projekts sind einige der Tests nur noch teilweise zugänglich, weil das Backend Daten nach 90 Tagen löscht (Abb. 1).

Abb. 1: Google sollte Flood It! und MechaHamster häufiger testen

Da die beiden von Google bereitgestellten Sample-Projekte von Entwicklern nicht verändert werden dürfen, sollten Sie alle im Studio geöffneten Projekte durch Anklicken von FILE | CLOSE PROJECT schließen. Wählen Sie dann die Option IMPORT AN ANDROID CODE SAMPLE aus, um Android Studio zum Herunterladen aller in der IDE verfügbaren Codebeispiele aus dem Hause Google zu animieren.

Wählen Sie im nächsten Schritt UI | HORIZONTAL PAGING und klicken Sie auf NEXT, um das Herunterladen des Programms anzuweisen. Die einzelnen Arbeitsschritte des Assistenten sind im Großen und Ganzen selbsterklärend – dank des Gradle-Build-Systems kann Android Studio fehlende Komponenten dynamisch aus dem Internet herunterladen.

Er kompiliert nicht?
Google hat die unangenehme Eigenschaft, einmal veröffentlichte Programmbeispiele nicht oder nur sehr leidlich zu warten. Wundern Sie sich deshalb nicht darüber, wenn Sie Targets, minSdk-Version und andere Attribute Ihres Beispielprojekts anpassen müssen, bevor dieses kompilierbar ist.

Klicken Sie im nächsten Schritt auf den Knopf CREATE A PROJECT, um den Assistenten zum Anlegen eines neuen Projektskeletts auf den Bildschirm zu holen. Google zwingt Ihnen hierbei das Anlegen eines vollwertigen Firebase-Projekts auf; vergeben Sie als Namen, was immer Sie als sinnvoll erachten. Nach dem erfolgreichen Anlegen finden Sie sich auf dem Startbildschirm wieder, der fortgeschrittene Features von Firebase feilbietet. Wer, wie wir, allerdings nur testen möchte, klickt im Menü auf STABILITY | TEST LAB.

Das Anlegen eines einfachen Tests erfolgt dabei ohne komplizierte Interaktionen mit Android Studio. Weisen Sie die IDE einfach dazu an, eine APK-Datei (Android Package Kit) zu erzeugen, und jagen Sie diese per Drag and Drop in Richtung von Googles Servern. Nach dem Hochladen der Datei – sie muss nicht signiert sein, sondern kann einfach durch Anklicken der Menüoption BUILD APKS erzeugt werden – läuft ein Validierungstest durch, der einige Sekunden in Anspruch nimmt.

Danach finden Sie sich in einer neuen Testmatrix wieder, die die gerade hochgeladene APK-Datei zur Bearbeitung bereitstellt. Zudem weist Google automatisch einen ersten Robo test an, dessen Ausführung durch den von Android bekannten Wartekreisel angezeigt wird und zeitlich einige Minuten in Anspruch nehmen kann. Zur Füllung dieser Totzeit wollen wir hier einige Überlegungen anstellen, um mehr über den ablaufenden Prozess zu erfahren.

Mit der Herrschaft des Zufalls

Vor vielen Jahren setzte man im Hause PalmSource auf ein als „Gremlins“ bezeichnetes Testwerkzeug. Die dahinterstehende Idee war einfach: Ein im Emulator auf der Workstation laufendes Palm-OS-Programm wurde mit vom Zufallsgenerator erzeugten Tapp- und Eingabeereignissen ausgestattet. Je nach Aufbau des Programms konnte man so tief oder weniger tief in die Benutzerschnittstelle eindringen. Regelmäßige Aktivierungen der diversen Systemereignisse (wie des berüchtigten Global Find) sorgten dafür, dass Probleme in der Interaktion zwischen Applikationsprogramm und Betriebssystem untersucht werden konnten. Ärgerlicherweise waren Gremlins bei der Fehlersuche nicht immer effizient. Das lag vor allem daran, dass man nach dem Auftreten eines Fatal Alerts nicht oder nur teilweise wusste, welche Klick- und Eingabesequenz das Programm am Ende über den Jordan schickte.

Google bietet mit Monkey ein ähnliches Werkzeug an, das in der Praxis allerdings unter den soeben besprochenen Problemen leidet. Robo test umgeht dieses Problem durch eine deterministische Vorgehensweise (Kasten: „Besser schlicht und einfach“). Hinter dieser auf den ersten Blick akademisch klingenden Ausdrucksweise verbirgt sich der Gedanke, dass ein Testlauf immer auf dieselbe Art und Weise abgearbeitet wird. Entwicklern stehen nur zwei Parameter zur Verfügung: Erstens Maximum Depth, mit dem sie die Tiefe festlegen dürfen. Ist der Wert weniger als 2, so verbleibt Robo test immer nur am Hauptbildschirm. Allgemein ist die dahinterstehende Vorgehensweise insofern einfach, als dass nach dem ersten Klick vom Hauptbildschirm aus ein Zähler mitläuft, der so lange erhöht wird, bis das Maximum erreicht wird. Danach kehrt Robo test zum Hauptbildschirm zurück, um einen neuen Durchlauf zu starten.

ML Conference 2019

Deep learning advances for signal processing

with Oleksandr Honchar (Mawi Solutions)

Towards meaningful AI

with Imola Fodor (Electrolux)

Kriterium Nummer zwei ist der Time-out. Zufallsgetriebene Tests können systembedingt nicht feststellen, wann ein Programm komplett getestet wurde – sie rackern einfach so lange, bis es dem Entwickler um die Rechenleistung schade ist. Im Fall von Robo test empfiehlt Google in der Dokumentation zumindest 2 Minuten Rechenzeit für kleine Programme, während komplexere Programme 5 Minuten bekommen sollten. Das ist auch der Standardwert, der von Android Studio beim direkten Hochladen einer APK-Datei angefordert wird.

Haben Sie unser APK vor dem Lesen dieses Abschnitts hochgeladen, so sollte ungefähr nun eine E-Mail von Google eingehen, die sie darüber informiert, dass der Test des Beispiels erfolgreich abgearbeitet wurde. Dies können Sie auch daran erkennen, dass der Wartekreisel durch einen grünen Haken ersetzt wurde.

Besser schlicht und einfach
Da Robo test mit den Steuerelementen auf eine intelligente Art und Weise zu interagieren sucht, muss das Programm über den inneren Aufbau der Views Bescheid wissen. Daraus folgt, dass WebViews und andere Elemente, die nicht aus dem GUI-Stack selbst kommen, nicht getestet werden können. Dass das Vorhandensein von Captchas dem Testprozess ebenfalls nicht zuträglich ist, folgt aus der Logik.

Da der von Google vorgegebene Test ein beliebiges Telefon auswählt und sonst nicht viel treibt, klicken wir im nächsten Schritt auf die Option Rund a Test Das Backend bietet Ihnen daraufhin die Option an, verschiedene Arten von Test anzulegen. Wir wollen in den folgenden Schritten abermals einen Robo test ausführen und laden die APK-Datei wie gewohnt hoch.

Bei einem nicht von Google angelegten Test dürfen Sie im nächsten Schritt unter dem etwas irreführenden Namen SELECT DIMENSIONS auswählen, welche Geräte zum Test eingesetzt werden sollen. Achten Sie dabei darauf, dass Google physikalische und virtuelle Geräte unterscheidet: Ein physikalisches Gerät ist ein in einem Serverrack stehendes Android-Smartphone, während ein virtuelles Gerät ein von Google gehostetes Android Virtual Device (AVD) ist. Zum Zeitpunkt der Drucklegung bietet Google einige Dutzend verschiedener Geräte an, in manchen Fällen dürfen sie – wie in Abbildung 2 gezeigt – sogar zwischen verschiedenen Versionen des Betriebssystems wählen.

Abb. 2: Die komplette Auswahl passt nicht auf den Bildschirm

Auf der Unterseite des Bildschirms können Sie beim Aktivieren des Schalters zur Bearbeitung fortgeschrittener Optionen auch die weiter oben besprochenen Parameter einstellen. Sodann können Sie den Test ausführen. Ich empfehle für die folgenden Schritte allerdings, dies nicht zu tun. Mit einem kostenlosen Account dürfen Sie pro Tag nämlich nur fünf reale und zehn virtuelle Gerätetests durchführen, danach müssen Sie bis 12 Uhr (PST) warten. Auch im niederen bezahlten Plan bleibt diese Beschränkung aufrecht: Wer unlimitiert testen möchte, muss die sehr teure Blaze-Option buchen. Reale Geräte kosten 5 US-Dollar pro Stunde, während Tests in AVDs mit 1 US-Dollar pro Stunde zu Buche schlagen.

Auswertung der Ergebnisse

Da Google nach dem Hochladen unserer APK-Datei sowieso einen Test durchgeführt hat, klicken wir nun auf den Namen des Tests, um die schon von den Beispielprojekten bekannte Liste der Testmatrizen auf den Bildschirm zu holen. Das von Google durchgeführte Experiment beschränkte sich dabei auf 1 Pixel API-Level 26. Beim Anklicken dieser Option kommen Sie auf den in Abbildung 3 gezeigten Bildschirmabschnitt.

Abb. 3: Die Auswertungsmöglichkeiten von Firebase Test Lab sind erstklassig

Neben der zu erwartenden Ausgabe von LogCat gibt es auch Screenshots, ein Video und sogar eine Aktivitätsübersicht, die eine Art Flussdiagramm der durch das Programm laufenden Bewegungen darstellt. Kurz gesagt ist es nicht sonderlich schwer, den Verlauf zu analysieren.

Zufall mit Regel

Es ist oft wünschenswert, eine Gruppe von Aktionen bei jedem Durchlauf von Robo test abzuarbeiten. Dies lässt sich über Skripte bewerkstelligen. Es handelt sich dabei um eine Anweisungsliste, die vom Runner abgearbeitet werden muss, bevor er sich – so noch Zeit übrig ist – der gewohnten zufälligen Belästigung der Applikation zuwenden kann.

Bevor wir uns mit der eigentlichen Realisierung eines Robo-test-Skripts auseinandersetzen, sei ein allgemeiner Hinweis erlaubt. Robo test beschränkt sich auch beim Hochladen eines Skripts auf jene Elemente, die hausgemacht sind. Enthält Ihr Programm ein Social-Media-SDK, so wird der Test dieses bzw. die von ihm erzeugten Formulare auch dann nicht berühren, wenn Sie die Klickfolge im Skript anlegen.

Kehren Sie zum Anlegen eines neuen Skripts in Android Studio zurück und klicken auf TOOLS | FIREBASE. Die IDE reagiert darauf mit dem Einblenden eines Assistentenfensters, in dem sie die Rubrik TEST LAB anklicken. Im nächsten Schritt wählen Sie die Option RECORD ROBO SCRIPT AND USE IT TO GUIDE ROBO TEST aus, um den dafür vorgesehenen Wizard auf den Bildschirm zu holen.

Die erste Aufgabe ist das Anklicken des Buttons RECORD ROBO SCRIPT: Android Studio blendet daraufhin den vom gewöhnlichen Debugger bekannten ADB-Dialog ein, in dem Sie entweder ein virtuelles oder ein reales Gerät auswählen dürfen. Es wird sodann wie gewohnt angeworfen und mit der zum Testen vorgesehenen Applikation beladen. Nach dem erfolgreichen Start des Programms erscheint ein leeres Fenster mit der Überschrift RECORD YOUR ROBO SCRIPT. Klicken Sie im Emulator herum, um zu sehen, dass das Fenster wie in Abbildung 4 gezeigt mit Informationen befüllt wird.

Abb. 4: Das Anklicken von Steuerelementen sorgt dafür, dass Ereignisse in der Ereignisliste aufscheinen

Nach dem Anklicken von OK können Sie die Datei an einen beliebigen Platz speichern, um sie später im Rahmen eines automatisierten Anlegens eines neuen Laufs hochzuladen. Da sich ein geskripteter Testlauf im Großen und Ganzen wie seine gewöhnlichen Kollegen verhält, wollen wir auf sein Handling hier schon aus Platzgründen nicht weiter eingehen.

Test in Akkurat

Mögen zufällige Tests besser als nichts sein, so wünscht man sich in der Praxis doch irgendwann die Möglichkeit, komplexere Untersuchungen durchzuführen. Firebase Testing Labs realisiert dies über sogenannte Instrumentierungstests, die auf Basis der Testframeworks Espresso und UI Automator 2.0 durchgeführt werden (Kasten: „IP-Adressbereiche“). Die in früheren Versionen des Produkts enthaltene Unterstützung für Robotium wurde mittlerweile ersatzlos eingestellt, diesbezügliche Tutorien sind nicht mehr anwendbar.

Der Aufwand für die Einrichtung eines Tests mag nicht unerheblich sein, amortisiert sich in der Praxis aber. Ein Test wird auf einem physikalischen Gerät nämlich mit bis zu 30 Minuten Rechenzeit ausgestattet, während Sie auf einer virtuellen Maschine sogar eine Stunde lang für Durchsatz sorgen dürfen.

Beachten Sie, dass Google in der Dokumentation die Nutzung von Firebase Test für Stresstests des Backends explizit untersagt. Im Moment ist zwar nicht bekannt, wie man dies umsetzt. Da der Suchmaschinenanbieter allerdings auch der Betreiber des größten Distributionskanals ist, ist Paranoia empfehlenswert.

IP-Adressbereich
Falls Sie virtuelle bzw. im Test-Lab befindliche Geräte zur Laufzeit erkennen möchten, können Sie dies über die von Google veröffentlichten IP-Adressbereiche tun. Zum Zeitpunkt der Drucklegung sind alle realen Geräte im Bereich 108.177.6.0/23 angesiedelt, während virtuelle Maschinen einige Subnetze für sich haben:

Virtual devices
  35.192.160.56/29
  35.196.166.80/29
  35.196.169.240/29
  35.203.128.0/28
  199.192.115.0/30
  199.192.115.8/30
  199.192.115.16/29

Wer mit aktuellen Versionen von Android Studio ein Projektskelett erzeugt, bekommt zwei Gruppen von automatisierten Tests eingeschrieben. Erstens die im Verzeichnis MODULE-NAME/SRC/TEST/JAVA/ liegenden klassischen Unit-Tests, die mit einer beliebigen VM ausgeführt werden und zum Überprüfen der Korrektheit von Algorithmen vorgesehen sind. Zweitens gibt es die im Ordner MODULE-NAME/SRC/ANROIDTEST/JAVA/ liegenden Teile, die für das Testen der Benutzerschnittstelle unter Nutzung der diversen Instrumentierungs-APIs auf der Android-Plattform vorgesehen sind. Da Google keine wirklich brauchbaren Beispiele anbietet, erstellen wir an dieser Stelle von Hand ein neues Projektskelett. In den Instrumentierungstests findet sich der in Listing 1 gezeigte Testfall, der die Struktur demonstriert.

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
  @Test
  public void useAppContext() throws Exception {
    Context appContext = InstrumentationRegistry.getTargetContext();
    assertEquals("com.tamoggemon.susinstrumentation", appContext.getPackageName());
  }
}

Instrumentierungstests sind unwissenschaftlich betrachtet Unit-Testfälle, die in einer Android JVM ausgeführt werden. Daraus folgt, dass Sie diverse Android-Systembestandteile in Ihre Unit-Tests einbeziehen können. Wir nutzen beispielsweise assertEquals, um den Paketnamen mit dem Rückgabewert der Android-Systemfunktion appContext.getPackageName() zu vergleichen.

Zum Testen der diversen GUI-Elemente bietet das Testframework eine Gruppe von Unterstützungsklassen an. Zum Überprüfen der Inhalte von Activities empfiehlt sich die etwas seltsam benannte Klasse ActivityInstrumentationTestCase2 – sie erzeugt die Activity bei Bedarf und kann eine am Bildschirm befindliche Instanz allerdings ebenfalls ergreifen. Zu ihrer Nutzung müssen wir im ersten Schritt eine neue Klasse im Testprojekt anlegen, deren Deklaration folgendermaßen aussieht:

public class TestTheActivity extends ActivityInstrumentationTestCase2 {
  public TestTheActivity() {
    super("com.tamoggemon.susinstrumentation", MainActivity.class);
  }

Eine weitere haarige Stelle ist das Anlegen von Testfällen. Das Ausführungsframework erreicht diese nämlich durch Reflektion des jeweiligen Funktionsnamens, der mit dem String test beginnen muss. Unser erster, nicht sonderlich aussagekräftiger Test sieht dann folgendermaßen aus:

public void testTheTitle(){
  Activity activity = getActivity();
  assertEquals("SUSInstrumentation",activity.getTitle());
}
}

Da die Ausführung von Testfällen in der Cloud die weiter oben genannten Credits verbraucht, ist es empfehlenswert, vor dem Hochladen einen Test unter Nutzung eines Emulators oder eines lokalen physikalischen Geräts loszulassen. Hierzu reicht es aus, den Ordner mit den Testfällen in Android Studio rechts anzuklicken und die Option Run zu wählen – das Produkt kümmert sich dann selbsttätig darum, eine Ausführungsumgebung aufzusetzen und einen ersten Probelauf durchzuführen. Scheitert dieser schon lokal, so wissen Sie, dass Sie ein Problem haben.

Von besonderem Interesse ist die Reaktion des Produkts beim Erzeugen einer APK-Datei: Anstatt wie gewöhnlich ein APK zu generieren, erzeugt Android Studio nun zwei Dateien (Abb. 5).

app-debug.apk ist hierbei an das gewöhnliche Applikations-APK angehängt, während app-debug-androidTest.apk die diversen Testfälle bereitstellt. Beim Anlegen einer neuen Testmatrix sind beide Dateien erforderlich. Laden Sie die Files hoch und folgen Sie den Anweisungen am Bildschirm, um wie gewohnt Geräte auszuwählen.

Ludologischer Test

Spiele zu testen, war noch nie leicht: Zufällige Eingaben führen nicht zum Ziel, zudem sorgt die Nutzung von Engines wie Unity dafür, dass intelligente Test-Runner wie Robo an der Evaluation des Benutzerinterface scheitern. Das liegt daran, dass die Engine normalerweise direkt in den Framebuffer zeichnet – View, Button, TextView und sonstige per Reflexion sichtbare Klassen sucht man im Allgemeinen vergebens.

Google begegnet diesem Problem durch ein als Game-Loop-Test bezeichnetes Feature, das derzeit allerdings noch in der Betaphase ist. Wir möchten seine Möglichkeiten allerdings trotzdem kurz anschneiden. Die Nutzung eines Game-Loop-Tests beginnt mit dem Einbinden eines speziellen Intent-Filters, der nach dem in Listing 2 gezeigten Schema aufgebaut sein muss.

<intent-filter>
 <intent-filter>
  <action
android:name="com.google.intent.action.TEST_LOOP"/>
  <category
android:name="android.intent.category.DEFAULT"/>
  <data
android:mimeType="application/javascript"/>
</intent-filter>

Wichtig ist in diesem Zusammenhang nur, dass es ausschließlich für die Verwendung der Game-Loop-Tests vorgesehen sind – es ist nicht erlaubt, die Filter zu kombinieren. Andererseits spricht allerdings nichts dagegen, die Activity mit mehreren unabhängigen Filtern auszustatten. Zur Laufzeit muss die jeweilige Activity überprüfen, ob sie normal oder im Schleifenmodus angeworfen wurde. In zweitem Fall muss Ihr Code einen Selbsttest durchlaufen; über dessen Aufbau macht Google keine Angaben.

Fazit

Informatiker neigen dazu, an die Existenz von Silberkugeln zu glauben. Firebase Test Lab ist dies mit Sicherheit nicht– drei Dutzend Geräte decken den Gesamtmarkt nicht ab. Dies bedeutet allerdings nicht, dass das Produkt keinen Platz in der Werkzeugkiste eines diensterfahrenen Android-Entwicklers haben sollte. Sind Tests erst automatisiert, so können Sie sie mit minimalem Aufwand ausführen. Auf die Art entsteht eine zusätzliche Qualitätssicherung, die den einen oder anderen Fehler einfängt.

Fehlervermeidung bleibt eine olympische Disziplin: Je mehr Sicherheitsmaßnahmen Sie einbauen, desto wahrscheinlicher ist es, dass sie nicht ob eines dummen Programmierfehlers einige Dutzend Ein-Stern-Bewertungen erhalten.

Entwickler Magazin

Entwickler Magazin abonnierenDieser Artikel ist im Entwickler Magazin erschienen.

Natürlich können Sie das Entwickler Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -