7 min read

Im ersten Teil habe ich darüber berichtet, wie wichtig der Softwareentwicklungsaspekt in der Test-Automation ist und das UI Test-Automation etwas ist, dass mit dem nötigen Ernst entwickelt werden muss. In diesem Teil möchte ich über meine Erfahrungen mit Testumgebungen reden und wie man in großen Organisationen mit Rollen, Rechte und Sicherheitsrichtlinien umgeht. Und natürlich darf das Thema Tooling in UI Test-Automation nicht fehlen.

 

Save the Environment

Ich erinnere mich an folgende Situation: Es war Freitag nach einer sehr anstrengenden frustrierenden Woche. Ich war zu diesem Zeitpunkt circa 4 Monate in einem Kundenprojekt. Das Refactoring der bestehenden Solution war abgeschlossen (soweit beim Refactoring jemals von einem Abschluss gesprochen werden kann). Die angeforderten Regressionstests waren implementiert und ich hatte Anforderungsmeetings mit den verantwortlichen Product Ownern. Neue Features wurden zu diesem Zeitpunkt mit circa einem halben Sprint Versetzung vom Test-Automation Framework getestet.

 

Die Situation:

Wie jeden Morgen überprüfte ich auch am Montagmorgen besagter Woche meine Testreports.

100% der Tests sind fehlgeschlagen.

Noch nicht weiter schlimm, ich wusste, dass Sonntagabend beim Kunden Batches remote eingespielt und Systeme neu gestartet werden. Dadurch müssen die Nodes des Selenium Grids manuell gestartet werden. Es gibt Tasks, die beim Hochfahren des Systems der Clients die Nodes starten sollte, aber wer weiß was da schon alles schiefgegangen sein mag. Nachdem die Testumgebung bereit war, konnten die entsprechenden Jenkins Jobs getriggered werden. Eine kurze Frühstückspause später musste ich feststellen, dass alle Tests erneut fehlgeschlagen waren. Ich überprüfte das Test-Automation Framework lokal auf meiner Workstation und es funktionierte alles.

In den nächsten Absätzen werde ich das „aber“, welches an dieser Stelle natürlich folgen muss, genauer ausführen. Dafür werde ich in die technischen Details des Settings hineinzoomen. Leser, die mit Selenium und dem Test von Webapplikationen nicht gut vertraut sind, mögen mir diesen technischen Exkurs verzeihen und beim „Fazit der Situation“ weiterlesen.

Bis ich herausgefunden hatte, dass es auf zwei von drei Nodes automatische Chrome Updates gegeben hat, war ein ganzer Vormittag vergangen. Es dauerte einen halben Nachmittag herauszufinden, dass es einen Bug im verwendeten Selenium ChromeDriver gab, der mit den neuen Sicherheitseinstellungen von Chrome nicht umgehen konnte.

Der Bugfix von Selenium/Chromedriver wurde am Mittwoch darauf veröffentlicht und hätte funktionieren sollen. Hätte … tat er aber nicht.

Es hat mich einen ganzen Tag gekostet herauszufinden, dass der Kunde, Chrome Extensions auf eine Whitelist setzt und ChromeDriver bei Start einer neuen Chrome Instanz eine neue Automatisierungsextension entpackt und diese installiert. Dabei handelt es sich, wie soll es anders sein, um keine offizielle Extension aus dem Chrome Web Store. Der Kunde kann aus Sicherheitsgründen diese Extension nicht auf die Whitelist setzen, und so musste die Extension manuell in die Registry eingetragen werden.

Der Montag an sich, oder eigentlich die gesamte Woche wäre nicht weiter schlimm gewesen. Die Test-Automation läuft auf mehr als nur einen Browser. In diesem Fall Firefox.

Ganz nach dem Motto, ein Bug kommt selten allein, haben die Firefox Tests am Montag ebenfalls nicht funktioniert (gemerkt habe ich dieses erst am Dienstag, da ich am Montag mit Chrome ausgelastet war). Auch hier gab es ein automatisches Update. Diesmal waren es keine Extensions, die Probleme machten, sondern die Zertifikatsverwaltung.

Kurze Erklärung: Im Kundenumfeld wird ein Enterprise Root Zertifikat benötigt, um mit dem Browser aus dem internen Netzwerk zu kommen; das Zertifikat ist in der Windows Zertifikatsverwaltung hinterlegt. Firefox verwaltet seine Zertifikate eigens und greift nicht auf die Windows Zertifikatsverwaltung zu. Dadurch muss in jedes Profil das Enterprise Root Zertifikat manuell eingespielt werden. Jede vom Geckodriver gestartete Instanz, legt ein neues Firefox Profile an. Der Geckodriver hat eine Funktion, die es ermöglicht das Zertifikat mitzugeben, aber nicht in einem Selenium Grid Environment. Da gab es zu dem Zeitpunkt einen Bug.

Durch die Komplexität des Environments und der Menge an Abteilungen, mit denen ich sprechen musste, um alle Informationen zu erlangen, die ich benötigte, um die Probleme erst zu erkennen und dann zu lösen, war die Test-Automation eine knappe Woche komplett lahmgelegt.

 

Wie kann mit der Situation umgegangen werden?

DON’T PANIC! Komplexe Umgebungen mit noch komplexeren Rollen- und Rechtesystemen, die historisch gewachsen sind, sowie lieblos geklonte Testumgebungen, die meist mit viel zu wenig Speicher virtualisiert sind, kommen leider sehr häufig vor. Es kommt immer wieder zu Daten oder auch Versionsunterschieden zwischen Test-, Staging- und Produktionsumgebung, die nicht beeinflusst werden können.

Ich nenne das "die äußeren Einflüsse". Selbst wenn die Testautomatisierung vermeintlich richtig aufgesetzt ist, manche Dinge liegen außer unserer Kontrolle.

In diesen Fällen kann meiner Meinung nach nichts anders gemacht werden, als mit den entsprechenden Personen zu reden, regelmäßig auf bestehende Probleme hinzuweisen und Ruhe zu bewahren. Es wird sich irgendeine Lösung finden.

Ideal für den Umgang mit solchen Problemstellungen sind Organisationen, die sich mit DevOps auseinandersetzen und die die damit verbundenen Prinzipien ernst nehmen und auch leben.

 

Tools, Tools, Tools

Jeder liebt es, Werkzeuge zu benutzen und liebt es, Tools in seine Systemumgebung zu integrieren. Und es gibt eine schier unendliche Anzahl von Tools zur Testautomatisierung. Meiner Meinung nach, gibt es zwei große Probleme, wenn es um die Wahl des richtigen Tools geht:

  1. Als TA – Experte haben wir die Qual der Wahl – Das „Paradox of Choice“.
  2. Die falschen Personen in einer Organisation entscheiden meistens am Ende welche Tools verwendet werden sollen, meistens ohne das nötige Wissen zu haben, um eine fundierte Entscheidung treffen zu können.

 

Die Situation:
Ich war kürzlich zwischen zwei Projekten, also hatte ich eine kleine Auszeit. Ein Kollege fragte mich, ob ich ihm  bei einer Testautomatisierungs-Situation bei einem Kunden unterstützen kann. Sicher, da ich noch ein paar Tage hatte bis das nächste Projekt startete sprach nichts dagegen.

Am nächsten Montag haben wir uns beim Kunden im Büro getroffen, er zeigte mir das zu testende System (SUT), eine Webanwendung, die stark angepasst wurde, sowie die Testautomatisierungs-„Solution". Ich möchte nicht auf irgendwelche Tools eintreten, aber der Kunde verwendete ein Tool eines österreichischen Herstellers, das weltweit bekannt und sehr teuer ist. Zuvor gab es keine Analyse- oder Akquisephase, in der geprüft wurde, ob das SUT mit diesem Tool testbar ist.

Spoiler: Das war es nicht.

Warum entschied sich der Kunde für den Einsatz des Tools? Ganz einfach, sie hatten bereits eine Lizenz und es wurde nur selten benutzt. Der Kunde bzw. mein Kollege hatte bisher drei Testfälle zusammengestückelt (ja, das Tool bietet keine Möglichkeit, Code oder Skripte zu schreiben), und in der Theorie sollten die Module wiederverwendbar waren und Daten dynamisch übergeben werden können. So weit so gut, oder so dachte ich.

Ich hatte zehn Tage Zeit, bevor ich mit dem neuen Projekt anfangen musste, und das Ziel war es, die Top 10 Testfälle für die wichtigsten Anwendungsfälle zu implementieren, datengesteuert und wiederverwendbar, drei davon waren schon da, nur mehr sieben zu implementieren - easy.

Was macht man, bevor man mit der Implementierung beginnt? Man prüft, ob das was man hat überhaupt funktioniert. Ich startete also den Testlauf und beobachtete, was passierte.

Nichts.

Nach der Analyse wurde mir klar, dass der Testlauf eine Extension benötigt, um Chrome und dann Elemente innerhalb der Website zu finden.

Ich installierte die Erweiterung und startete den Test erneut.

Und nichts.

Ich habe mir die Fehlermeldung angesehen. Ein " couldn’t find element exception". Ich untersuchte das Element, es handelte sich dabei um eine Eingabefeld für den Benutzernamen, dieses Element hatte sogar eine ID. Ich überprüfte das Element im Tool, gleiche ID.

Seltsam. Ich überprüfte den Testfall, der das Element verwendet, die Referenz scheint korrekt zu sein.

Ich habe eine halbe Stunde verschwendet, bevor ich darüber nachdachte, das Eingabefeld für den Benutzernamen neu zu scannen und damit ein neues Element zu erstellen. Danach hat es funktioniert.

Die ersten drei Tage stieß ich auf so viele und seltsame Probleme.

  • Elemente in der Webanwendung konnten von einem Testlauf zum nächsten nicht mehr angesprochen werden, ohne Grund.
  • Der gleiche Testfall mit unterschiedlichen Datensätzen: ein Mal mit „Pass“ durchgelaufen und beim zweiten Lauf ohne Grund fehlgeschlagen.
  • Ich habe einen ganzen Tag damit verbracht, den Test runner mit Chrome zu verbinden. Ich habe alle vorgeschlagenen Punkte in der offiziellen Dokumentation durchgeführt, etwa 8 und es funktionierte immer noch nicht. Bei meinem letzten Versuch, bevor ich mich geschlagen gegeben hätte, funktionierte es plötzlich wieder.

Am Ende des vierten Tages hatte ich immer noch nichts anderes, als einen sehr großen Hass auf dieses spezielle Tool.

Am fünften Tag sprachen mein Kollege und ich mit dem Projektverantwortlichen, und wir sagten ihm, dass es mit dem Tool nicht funktionieren wird. Wenn er ein brauchbares Ergebnis haben will, brauchen wir etwas, das robust ist und schnell implementiert ist. Er gab uns grünes Licht, und ich begann mit der Implementierung einer codebasierten Lösung mit Java, Junit als Testframework und Selenium als Driver um auf das SUT zuzugreifen.

 

Wie kann mit der Situation umgegangen werden?

Das Schreiben von codebasierter Testautomatisierung ist kein Allheilmittel. Aber man kann im Grunde alles implementieren das benötigt wird, wenn man ein grundlegendes Verständnis für das Schreiben von Code hat. In der obigen Situation konnte ich die Anforderungen nur deswegen in der verbleibenden  Zeit umsetzen, weil wir bei Nagarro so viel Erfahrung in der QA und Testautomatisierung haben. Wir haben einen robusten und bewährten Ansatz und ein gut implementiertes Framework, das alles bietet, was man für einen schnellen Start benötigt.

Bevor man sich überlegt, ob eine Lizenz erworben werden soll, sollte man sich ein paar Fragen beantworten. Dabei sollte man wirklich kritisch und herausfordernd sein, um herauszufinden, was in einem Team/in einer Organisation gebraucht wird und wie das Tool dann auch unterstützen kann:

  • Benötigt man ein Tool mit monatlicher/jährlicher/Benutzer-Lizenzgebühr?
  • Benötigt man ein Tool, für dessen Handhabung eine große Lernkurve erforderlich ist
    • Das bedeutet, dass man eine Wissensinsel aufbaut.
  • Gibt es einen anderen Weg, um das vom Tool benötigte zu simulieren? Vielleicht ist das Wissen zur Zielerreichung bereits im Team/in der Organisation?
  • Wie robust können Testfälle gestaltet werden?
  • Wie schwer ist es, wiederverwendbare Keywords zu erstellen?
  • Wie schwierig ist es, die TA in eine Build-Pipeline zu integrieren?
  • Wie schwierig ist es, die TA in das verwendete Ticketsystem zu integrieren?
  • Ist die Versionierung mit Standard-Tools wie Git möglich?

Meiner Erfahrung nach gibt es kein Tool, das die nötige Bandbreite zur Verfügung stellt, um die Komplexität eines Systems komplett abzudecken. Es ist fatal, eine Testautomatisierung um ein Tool herum aufzubauen, das nicht genügend Integration von anderen Tools/Bibliotheken unterstützt (nicht notwendige Testautomatisierungswerkzeuge).

Wie man sich vorstellen kann, bin ich aus verschiedenen Gründen wirklich kein Fan von Click & Replay Tools. Aber ein Grund sticht besonders hervor: Kunden neigen dazu, Tools länger zu behalten, als es ihnen gut tut.

 

Fazit – Testautomatisierung ist hochspezialisierte Softwareentwicklung!

Es gibt viel zu tun. Jeder braucht oder will UI Test-Automation. Die Wenigsten sind sich allerdings bewusst, was das wirklich bedeutet. Heute mehr denn je entwickelt sich UI Test-Automation zu einer eigenen Disziplin in der Softwareentwicklung. Und es ist genau das: hochspezialisierte Softwareentwicklung. Es ist wichtig, jungen Einsteigern und „alten Hasen“ die richtigen Werkzeuge zu geben, mit denen sie ihr Team unterstützen und das Projekt zu einem Erfolg machen können.