Florian Pilz

Estimated reading time: 6 Minuten

Tech im Fokus

Wie ich unser Appium-Projekt von Java auf Kotlin umzog…

Ich betreue in meinem Projekt die Testautomatisierung. Wir verwenden Appium (Java), um unsere Android- und iOS-Apps zu automatisieren. Zusätzlich kommen TestNg als Testrunner und jGiven als BDD-Framework zum Einsatz. Vor Kurzem startete ich damit, den Test Code zu refactoren. Mein Ziel war es, den Code zu vereinfachen und neu zu strukturieren, und ihn dadurch besser…

Software-Testing
Testautomatisierung
Testsanierung

Ich betreue in meinem Projekt die Testautomatisierung. Wir verwenden Appium (Java), um unsere Android- und iOS-Apps zu automatisieren. Zusätzlich kommen TestNg als Testrunner und jGiven als BDD-Framework zum Einsatz. Vor Kurzem startete ich damit, den Test Code zu refactoren. Mein Ziel war es, den Code zu vereinfachen und neu zu strukturieren, und ihn dadurch besser wartbar zu gestalten.

Vor einiger Zeit hatte ich von Kotlin gelesen und mir war in Erinnerung geblieben, wie leichtgewichtig und einfach diese Sprache sein soll. Für mein Refactoring nahm ich mir vor, die Sprache auszuprobieren.

Magic Button

Einer der großen Vorteile von Kotlin ist, dass es nahezu reibungslos mit Java zusammen funktioniert. Die Sprache von JetBrains wird entwickelt, der Firma hinter IntelliJ. Das vereinfachte die Umstellung enorm: JetBrains hat einen magischen Button „Convert Java to Kotlin“ in IntelliJ eingebaut. Damit konnte ich recht einfach starten: Ich suchte mir einfache PageObjects, erstellte eine Kopie, und konvertierte die Originale von Java nach Kotlin. Da mir dieselbe Datei nun in Java (Kopie) und in Kotlin (Original) vorlag, konnte ich im Vergleich der beiden Versionen lernen wie die Syntax in der einen Sprache und in der anderen Sprache aussieht. Immer wieder ließ ich die Tests laufen, um zu prüfen, ob noch alles funktioniert. Und was soll ich sagen: Alles lief reibungslos.

Probleme traten lediglich bei Klassen auf, die sich selbst als Typ haben (bspw. TouchActions). Dies konnte ich mit Hilfe unserer Android-Entwickler lösen. (Die Lösung: Wir erstellten eine nicht generische Klasse, welche bspw. von TouchActions erbt – mehr gibt es im Appium-Forum zu lesen.)

Nachdem alle PageObjects auf diese Weise konvertiert waren, nahm ich mir den nächsten Code-Teil vor und konvertierte auch diesen. Dadurch gelangte ich in wenigen Tagen vom Zustand „Ich habe keine Ahnung von Kotlin – schauen wir uns doch mal an, was die Sprache so kann“ zu „So, fertig, alles umgestellt und die Tests laufen immer noch“.

Never change a running system?

Wie beschrieben ist ein großer Vorteil von Kotlin, dass es mit Java zusammen funktioniert. Man kann es also an einer Stelle ausprobieren. Wenn man mit den Ergebnissen zufrieden ist, macht man weiter. Wenn nicht, stellt man das bisschen Kotlin-Code wieder auf Java um. Beim Ausprobieren verliert man also nicht großartig Inhalt.

Jetzt kann man berechtigterweise argumentieren „Never change a running system“: Warum sollte ich mein Testprojekt also überhaupt umziehen? Ich bin für mich – und auch KollegInnen im Projekt geht es so – nach dem Umzug ziemlich überzeugt davon. Hier ein paar Möglichkeiten warum:

  • Kürzere PageObjects: Unsere Implementierung sieht so aus, dass die Tests einen AppiumDriver erzeugen. Dieser wird an das gerade aktuelle PageObject übergeben, welche ihn an die Hauptseite übergibt. Diese Hauptseite enthält allgemeine Funktionen und Variablen, von ihr erben alle weiteren PageObjects. In Java sind das mehrere Zeilen Code, in Kotlin hingegen nur eine Zeile. Das Instanziieren der Oberklasse, inklusive Weiterreichen des AppiumDrivers, passiert direkt in der Kopfzeile des PageObjects.
  • Vereinfachte Funktionen: Sehr oft kommen in unserem Code Funktionen vor, die nur eine Zeile Code verwenden. Oft führen diese Dinge aus wie „Warte bis ein bestimmtes Element angezeigt wird, dann gib dessen Text zurück“. In Kotlin kann man hier viel Code einfach weglassen. So werden die geschweiften Klammern und das return-Schlüsselwort einfach durch ein „=“ ersetzt. Ebenso braucht es kein public-Schlüsselwort, den Rückgabetyp setzt Kotlin auch automatisch. Beides kann also auch weggelassen werden.
  • Globale Variablen: Wie oben beschrieben instanziieren wir den AppiumDriver in den Testklassen und reichen ihn von Test zu PageObject zu PageObject weiter. Kotlin lässt uns Variablen außerhalb von Klassen deklarieren. So habe ich den AppiumDriver als globale Variable definiert. Sie wird bei Teststart instanziiert und dann in allen weiteren Klassen verwendet; ein Weiterreichen ist also nicht mehr notwendig. Auch das macht den Code wesentlich kürzer und einfacher. Lediglich bei paralleler Testausführung muss darauf geachtet werden, dass der Driver threadsave gestaltet wird.
  • Data-Classes und Default Werte: Um Testdaten zu übergeben, verwenden wir jetzt Data-Classes. Diese Klassen speichern Daten. Die Properties der Data-Classes werden der Klasse als Parameter übergeben und können Default-Werte erhalten. Brauche ich genau diese Werte, so instanziiere ich lediglich die Data-Class und kann auf die Default-Werte zugreifen. Wenn sich ein bestimmter Wert verändert, ändere ich lediglich diesen. Kotlin hilft mir auch hier, indem es benannte Parameter ermöglicht.

Das sind nur ein paar Beispiele, wie ich unseren Test Code durch den Umbau vereinfachen konnte.

Lesbarer, verständlicher, wartbarer Code

War es die Arbeit also wert? Meine Antwort darauf lautet definitiv „Ja“. Die gesamte Umstellung von Java auf Kotlin dauerte nur wenige Tage – inklusive Lernen der Sprache. Man verliert also nur wenig Zeit. Auch die Unterstützung durch die IDE erleichtert den Umstieg ungemein. Die Menge des geschriebenen Codes hat sich deutlich verringert. Auch gibt es viele Möglichkeiten, den Code besser zu strukturieren. Das macht das Testprojekt insgesamt lesbarer, verständlicher und wartbarer.


Über den Autor

Florian Pilz