Erfahrung in der Implementierung von Automatisierung im Prozess des manuellen Testens am Beispiel einer Android-Anwendung

Ein guter Tester mit Fähigkeiten zum kritischen Denken kann nicht vollständig durch Automatisierung ersetzt werden. Es ist einfach, es effizienter zu machen. Mit dieser Überzeugung ging ich mit einer neuen Aufgabe zu unserer Testabteilung, wo wir zusammen mit Pavel die Implementierung aufnahmen. Mal sehen, was daraus wurde.

Gemeinsam mit unseren Partnern entwickeln, testen und unterstützen wir aktiv eine Reihe von Anwendungen für verschiedene Plattformen: Android, iOS, Windows. Es entwickeln sich aktiv Anwendungen, mit denen das Testvolumen zunimmt, vor allem die Regression.

Wir haben uns entschlossen, das Testen durch Automatisierung der meisten Testszenarien zu vereinfachen und zu beschleunigen. Gleichzeitig wollten wir den Prozess des manuellen Testens nicht vollständig aufgeben, sondern modifizieren.

Die Implementierung dieses Ansatzes begann mit einer der Android-Anwendungen, über die ich sprechen werde. Der Artikel ist für Anfänger von UI-Tests, vor allem für mobile Anwendungen, sowie für diejenigen von Interesse, die den manuellen Testprozess in gewissem Maße automatisieren möchten.

Lass uns gehen!

Ausgangspunkt


Für jede Plattform gibt es mehrere ähnliche Plattformen, die denselben Hauptgeschäftsprozess von Anwendungen ausführen. Sie unterscheiden sich jedoch in einer Reihe kleiner Zusatzfunktionen, werden je nach Kunde unter verschiedenen Marken hergestellt (aufgrund derer sich die Benutzeroberfläche von Anwendung zu Anwendung ändert), und der Geschäftsprozess kann durch Hinzufügen zusätzlicher Schritte angepasst werden.

Wir stehen vor bestimmten Problemen, die angegangen werden müssen. Ähnliche Schwierigkeiten können in einer anderen Situation als unserer auftreten. Wenn Sie beispielsweise eine umfangreiche Anwendung mit schwieriger Geschäftslogik haben, die mit vielen Tests überwachsen ist.

Problem Nr. 1: viele Regressionstests


Die Testszenarien für jede Anwendung sind gleichzeitig ähnlich und voneinander verschieden, was zu einer Erhöhung der Regression beiträgt und sie noch langweiliger macht. Sie müssen jedoch alle Anwendungen einzeln testen.

In Anbetracht der Tatsache, dass bereits ausgeführte Anwendungen regelmäßig aktualisiert werden und es in Zukunft nur noch mehr geben wird, wird die Gesamtzahl der Tests unaufhaltsam zunehmen.

Problem Nummer 2: Sie müssen auf allen Versionen des mobilen Betriebssystems testen


Eine wichtige Voraussetzung ist die Verfügbarkeit unserer mobilen Anwendungen auf einer Vielzahl von Betriebssystemversionen. Im Fall von Android zum Zeitpunkt des Schreibens sind dies beispielsweise API-Ebenen von 17 bis 28.

Idealerweise sollten wir auf jeder Android-Version testen, was unsere Regression weiter erschwert. Der Prozess des direkten Testens der Anwendung erhält eine zusätzliche Routine multipliziert mit der Anzahl der Geräte: Installieren und Ausführen der Anwendung, Versetzen in den ursprünglichen Zustand nach jedem einzelnen Test, Entfernen. Gleichzeitig ist die Pflege Ihrer eigenen Gerätefarm sehr arbeitsintensiv.

Lösung: Integrieren Sie die Automatisierung in den manuellen Testprozess



Eine typische Aufgabe der Testautomatisierung ist die Automatisierung von Regressionstests. Deshalb wollen wir die Effizienz des Testprozesses heute verbessern und die möglichen Folgen des Wachstums von morgen verhindern.

Gleichzeitig sind wir uns bewusst, dass es unmöglich und unnötig ist, manuelle Tests durch Automatisierung vollständig zu beseitigen. Kritisches Denken und das menschliche Auge sind schwer durch etwas zu ersetzen. Es gibt einen guten Artikel zu diesem Thema in Michael Boltons Blog The End of Manual Testing (oder einer Übersetzung von Anna Rodionova).

Wir dachten, es wäre nützlich, eine Reihe automatisierter Tests zu haben, die die stabilen Teile der Anwendung abdecken, und in Zukunft Tests für gefundene Fehler und neue Funktionen zu schreiben. Gleichzeitig möchten wir Autotests mit vorhandenen Testsuiten in unserem Testmanagementsystem verknüpfen (wir verwenden TestRail) und Testern die einfache Ausführung von Autotests auf physischen Cloud-Geräten ermöglichen (wir haben Firebase Test Lab als Cloud-Infrastruktur ausgewählt).

Zu Beginn haben wir eine unserer Android-Anwendungen verwendet. Es war wichtig zu berücksichtigen, dass bei Erfolg der Lösung die Best Practices auf unsere anderen Anwendungen angewendet werden können, auch auf anderen Plattformen.

Was wir als Ergebnis bekommen wollen:

  1. Automatisierung von Regressionstests.
  2. Integration in das Testmanagementsystem.
  3. Möglichkeit des parametrisierten manuellen Starts von Autotests auf Cloud-Geräten.
  4. Die Möglichkeit, die Lösung in Zukunft wiederzuverwenden.

Als nächstes werde ich separat über die Implementierung jedes dieser Punkte mit einem kleinen Eintauchen in die technische Komponente sprechen.

Allgemeines Lösungsimplementierungsschema


Aber zuerst ein allgemeiner Überblick darüber, was wir bekommen haben:

Bild

Automatische Tests werden auf zwei Arten ausgeführt:

  1. Von CI nach dem Zusammenführen oder Ziehen der Anforderung an den Master.
  2. Testen Sie manuell über die Jenkins Job-Weboberfläche.

Bei einem manuellen Start muss der Tester entweder die Nummer des entsprechenden Builds angeben oder 2 APKs vom Computer herunterladen: mit der Anwendung und mit den Tests. Diese Methode wird benötigt, damit Sie die erforderlichen Tests jederzeit auf allen verfügbaren Geräten ausführen können.

Während der Tests werden ihre Ergebnisse an TestRail gesendet. Dies geschieht auf die gleiche Weise, als ob der Tester den Test manuell durchgeführt und die Ergebnisse auf eine ihm vertraute Weise eingegeben hätte.

Daher haben wir den etablierten Prozess des manuellen Testens verlassen, aber die Automatisierung hinzugefügt, die eine bestimmte Reihe von Tests durchführt. Der Tester "nimmt" auf, was automatisch gemacht wurde, und:

  • sieht das Ergebnis von Testfällen auf jedem ausgewählten Gerät;
  • kann jeden Testfall manuell überprüfen;
  • führt Testfälle durch, die noch nicht automatisiert sind oder aus irgendeinem Grund nicht optimiert werden können;
  • trifft die endgültige Entscheidung über den aktuellen Testlauf.

Fahren wir nun mit der versprochenen Beschreibung der Implementierung fort.

1. Automatische Tests


Die Werkzeuge


Wir haben 3 Tools verwendet, um mit der Benutzeroberfläche zu interagieren:

  • Espresso
  • Barista.
  • UI Automator.

Das Hauptwerkzeug und das, mit dem wir begonnen haben, ist Espresso. Das Hauptargument für seine Wahl war die Tatsache, dass Sie mit Espresso Tests mit der White-Box-Methode durchführen können, um Zugriff auf Android Instrumentation zu erhalten. Der Testcode befindet sich im selben Projekt wie der Anwendungscode.

Der Zugriff auf den Android-Anwendungscode ist erforderlich, um seine Methoden in Tests aufrufen zu können. Wir können unsere Anwendung im Voraus auf einen bestimmten Test vorbereiten, indem wir sie im richtigen Zustand ausführen. Andernfalls müssen wir diesen Zustand über die Schnittstelle erreichen, die Atomizitätstests entzieht, sie voneinander abhängig macht und einfach viel Zeit in Anspruch nimmt.

Während der Implementierung wurde Espresso ein weiteres Tool hinzugefügt - UI Automator. Beide Frameworks sind Teil der Android Testing Support Library von Google . Mit dem UI Automator können wir mit verschiedenen Systemdialogen oder beispielsweise mit Notification Drawer interagieren.

Und das letzte in unserem Arsenal war das Barista-Framework. Es ist ein Wrapper um Espresso, der Ihnen den Boilerplate-Code erspart, wenn Sie allgemeine Benutzeraktionen implementieren.

Unter Berücksichtigung des Wunsches, die Lösung in anderen Anwendungen wiederverwenden zu können, ist zu beachten, dass die aufgeführten Tools ausschließlich für Android-Anwendungen bestimmt sind. Wenn Sie keinen Zugriff auf den Code der zu testenden Anwendung benötigen, bevorzugen Sie wahrscheinlich die Verwendung eines anderen Frameworks. Zum Beispiel das heute sehr beliebte Appium. Sie können aber auch versuchen, mit Hilfe von Backdoors zum Anwendungscode zu gelangen, was ein guter Artikel im Badoo-Blog ist. Sie haben die Wahl.

Implementierung


Als Entwurfsmuster haben wir Testroboter ausgewählt, die Jake Wharton im gleichnamigen Bericht vorgeschlagen hat . Die Idee dieses Ansatzes ähnelt dem allgemeinen Seitenobjekt-Entwurfsmuster, das beim Testen von Websystemen verwendet wird. Die Programmiersprache ist Java.

Für jedes unabhängige Fragment der Anwendung wird eine spezielle Roboterklasse erstellt, in der die Geschäftslogik implementiert ist. Die Wechselwirkung mit jedem Element des Fragments wird in einem separaten Verfahren beschrieben. Darüber hinaus werden hier auch alle in diesem Fragment durchgeführten Behauptungen beschrieben.

Betrachten Sie ein einfaches Beispiel. Das beschriebene Fragment enthält mehrere Felder zur Dateneingabe und eine Aktionsschaltfläche:

Bild

Der Code des Anmeldefunktionstests selbst:

Bild

Hier überprüfen wir das positive Szenario, wenn die eingegebenen Authentifizierungsdaten korrekt sind. Die Daten selbst werden den Eingabetests unterzogen oder die Standardwerte werden verwendet. Somit hat der Tester die Möglichkeit, hinsichtlich der Testdaten zu parametrisieren.

Diese Struktur bietet den Tests zunächst eine hervorragende Lesbarkeit, wenn das gesamte Skript in die Hauptschritte der Ausführung unterteilt ist. Die Idee, Aussagen auf die einzelnen Methoden des entsprechenden Roboters zu übertragen, hat uns auch sehr gut gefallen. Assert wird zum gleichen Schritt, ohne die allgemeine Kette zu durchbrechen, und Ihre Tests wissen immer noch nichts über die Anwendung.

In dem oben genannten Bericht gibt Jake Wharton eine Implementierung in Kotlin, wo sie endlich ist. Wir haben es bereits bei einem anderen Projekt versucht und es hat uns sehr gut gefallen.

2. Integration mit dem Testmanagementsystem


Vor der Einführung der Automatisierung haben wir alle unsere Tests im TestRail-Testmanagementsystem durchgeführt. Die gute Nachricht war, dass es eine ziemlich gute TestRail-API gibt , mit der wir bereits im System etablierte Testfälle mit Autotests verbinden konnten.

Während des Testlaufs mit JUnit RunListener werden verschiedene Ereignisse abgefangen, z. B. testRunStarted , testFailure , testFinished , in denen wir die Ergebnisse an TestRail senden. Wenn Sie AndroidJUnitRunner verwenden, muss er auf bestimmte Weise über Ihren RunListener informieren, wie in der offiziellen Dokumentation beschrieben.

Sie müssen auch mit verschiedenen TestRail-Entitäten über deren ID kommunizieren. @CaseId den Test mit dem entsprechenden Testfall zu verbinden, haben wir eine einfache Annotation @CaseId , deren Verwendung im obigen Beispiel für die @CaseId gezeigt wird.

Code zur Implementierung der Anmerkung selbst:

Bild

Es bleibt nur, um seinen Wert an der richtigen Stelle aus der Beschreibung zu erhalten:

Bild

3. Manueller Start von Autotests auf Cloud-Geräten


Startparametrierung in Jenkins Job


Um den manuellen Start von Autotests zu organisieren, verwenden wir den Free-Style Jenkins Job . Diese Option wurde gewählt, weil das Unternehmen bereits Erfahrung mit ähnlichen Arbeiten mit Jenkins Job in anderen Bereichen hatte, insbesondere mit DevOps-Ingenieuren, die sie gerne teilten.

Jenkins Job führt ein Skript aus, das auf Daten basiert, die von der Weboberfläche übertragen wurden. Somit ist die Parametrisierung von Testläufen implementiert. In unserem Fall initiiert das Bash-Skript den Start von Tests auf den Firebase-Cloud-Geräten.

Die Parametrierung umfasst:

  • Auswahl der gewünschten APK durch Angabe der Nummer des entsprechenden Builds oder manuelles Herunterladen.
  • Geben Sie alle Arten von Testdaten ein.
  • Eingabe zusätzlicher benutzerdefinierter Daten für TestRail.
  • Wählen Sie aus der im Firebase Test Lab verfügbaren Liste Cloud-basierte physische Geräte aus, auf denen Tests ausgeführt werden sollen.
  • Die Auswahl der durchzuführenden Testkits.

Schauen wir uns einen Teil der Webseite unseres Jenkins-Jobs anhand eines Beispiels für eine Geräteauswahloberfläche und Testsuiten an:

Bild

Jedes Element, in das Sie Daten eingeben oder auswählen können, wird von speziellen Jenkins-Plugins implementiert. Beispielsweise wird die Geräteauswahloberfläche über das Active Choices Plugin erstellt . Mit einem groovigen Skript von Firebase wird eine Liste der verfügbaren Geräte abgerufen, die dann in der gewünschten Form auf der Webseite angezeigt wird.

Nachdem alle erforderlichen Daten eingegeben wurden, wird das entsprechende Skript gestartet, dessen Fortschritt wir im Abschnitt Konsolenausgabe beobachten können:

Bild

Von hier aus kann der Tester, der den Testlauf initiiert hat, unter Verwendung der empfangenen URLs zu TestRail oder zur Firebase-Konsole wechseln, die viele nützliche Informationen zum Ausführen von Tests auf jedem der ausgewählten Geräte enthält.

Endgültige Testmatrix im Firebase-Testlabor


Die Gerätematrix in Firebase enthält die Verteilung der Tests nach den Geräten, auf denen sie ausgeführt wurden:

Bild

Für jedes Gerät können Sie das vollständige Protokoll, das Video des Testlaufs und verschiedene Leistungsindikatoren anzeigen. Darüber hinaus können Sie auf alle Dateien zugreifen, die möglicherweise während der Ausführung der Tests erstellt wurden. Wir verwenden dies, um Testabdeckungsindikatoren vom Gerät herunterzuladen.

Wir haben uns für Firebase entschieden, da wir diesen Service bereits zur Lösung anderer Probleme genutzt haben und mit der Preispolitik zufrieden sind. Wenn Sie 30 Minuten reine Zeit zum Testen pro Tag haben, müssen Sie überhaupt nicht bezahlen. Dies kann ein weiterer Grund sein, warum es wichtig ist, nur bestimmte Tests ausführen zu können.

Möglicherweise bevorzugen Sie eine andere Cloud-Infrastruktur, die auch gut zu Ihrem Testprozess passt.

4. Wiederverwenden


Wie kann all dies in Zukunft genutzt werden? Aus Sicht der Codebasis ist diese Lösung nur für Android-Anwendungen anwendbar. Während der Implementierung haben wir beispielsweise die UiAutomatorExtensions EspressoExtensions und UiAutomatorExtensions , in denen wir verschiedene Optionen für die Interaktion mit der Schnittstelle kapseln und warten, bis die Elemente bereit sind. Dies schließt auch die RunListener-Klasse ein, die für die Integration in TestRail verantwortlich ist. Wir haben sie bereits in separaten Modulen platziert und verwenden sie zur Automatisierung anderer Anwendungen.

Wenn wir über andere Plattformen sprechen, können die gesammelten Erfahrungen sehr nützlich sein, um ähnliche Prozesse aufzubauen und zu implementieren. Wir tun dies aktiv im iOS-Bereich und denken über Windows nach.

Fazit


Es gibt viele Optionen für die Implementierung und Verwendung der Testautomatisierung. Wir sind der Meinung, dass Automatisierung in erster Linie ein Werkzeug ist, das den traditionellen Prozess des "menschlichen" Testens erleichtern und nicht auslöschen soll.

Source: https://habr.com/ru/post/de434252/


All Articles