UI-Tests sind ein essenzieller Teil der mobilen App-Entwicklung, um sicherzustellen, dass eine App die bestmögliche Nutzererfahrung liefert. Aber wie macht man das in .NET MAUI, wenn Xamarin.UITest nicht mehr vollständig kompatibel ist? Schauen wir uns drei Alternativen an.
Wenn über Testautomatisierung gesprochen wird, fällt oft das Bild einer Pyramide, die die verschiedenen Ebenen automatisierter Tests zeigt: Unit-Tests bilden die Basis, UI-Tests die Spitze.
Unit-Tests sind inzwischen Standard in professioneller Softwareentwicklung. Sie prüfen Module gegen ihre Spezifikation. Sie reichen jedoch nicht aus, um sicherzustellen, dass das Zusammenspiel aller funktionalen Einheiten korrekt funktioniert.
Darüber liegen Integrationstests, also die mittlere Schicht der Testpyramide. Wenn man zum Beispiel eine Funktion testet, die Daten in eine Datenbank schreibt oder mit einem Webservice kommuniziert, dann reicht ein isolierter Unit-Test nicht mehr aus. Integrationstests überschreiten die Grenzen einzelner Einheiten und prüfen, ob mehrere Module korrekt zusammenarbeiten.
Unit- und Integrationstests lassen aber einen entscheidenden Faktor außen vor, sobald eine Anwendung irgendeine Form von Oberfläche besitzt: die Benutzeroberfläche. Genau dort interagieren Nutzer direkt mit einer App oder Website. Tests auf UI-Ebene erlauben es, typische Abläufe und wichtige Use Cases so zu prüfen, wie sie der Nutzer tatsächlich erlebt - über verschiedene Auflösungen, Ausrichtungen oder Designs hinweg.
Je weiter man in der Pyramide nach oben geht, desto höher werden Kosten, Laufzeiten, Komplexität und potenzielle Unzuverlässigkeit. Gleichzeitig steigt aber auch die Abdeckung und es reduziert sich der Aufwand für manuelle Tests.
Auf allen Ebenen der Pyramide streben wir den höchstmöglichen Automatisierungsgrad an. Gründe dafür sind:
Wiederholbarkeit und deterministische Ergebnisse
weniger Regressionen
weniger manuelle Tests und weniger Zeit für Bugfixes
geringere Kosten
Vor allem die Automatisierung häufiger Standardabläufe spart enorm viel Zeit. Diese Zeit kann stattdessen in das Testen von Randfällen oder in die Behebung echter Probleme investiert werden. Eine große automatisierte Testsuite hilft, Regressionen frühzeitig zu erkennen und spart auf Dauer sehr viel Aufwand.
Warum wir eine Alternative zu Xamarin.UITest brauchen
Je näher .NET MAUI an die Reife heranrückt, desto größer wird der Bedarf an einem kompatiblen und funktionalen UI-Test-Framework. Für Xamarin- und Xamarin.Forms-Apps war Xamarin.UITest lange die Standardlösung. Durch die enge Integration mit App Center konnten Tests auf App Center Test, früher Xamarin Test Cloud, auf einer großen Auswahl physischer Geräte ausgeführt werden.
Entwickler konnten damit außerdem native iOS- und Android-Apps in C# testen, wenn sie das wollten.
Sogar Backdoors wurden unterstützt. Damit lassen sich Methoden in der laufenden App aufrufen, die nicht direkt über die Oberfläche erreichbar sind. So könnte man etwa den Eingang einer Push-Benachrichtigung simulieren und prüfen, wie die UI darauf reagiert. Technisch gesehen verlässt man damit allerdings ein Stück weit die Grenze des Black-Box-Testings.
Es gab sogar einmal den Xamarin Test Recorder, mit dem sich App-Interaktionen aufzeichnen und daraus Testcode generieren ließen. Dieses Produkt wurde jedoch bereits im März 2018 eingestellt.
Die schlechte Nachricht: Seit Xamarin in die .NET-Welt überführt wurde, nimmt die Kompatibilität von Xamarin.UITest ab. Zum Zeitpunkt des ursprünglichen Artikels war das letzte NuGet-Update für .NET 6 erschienen, obwohl .NET 7 bereits veröffentlicht war.
Ich habe versucht, Tests für eine .NET-MAUI-App mit Xamarin.UITest zu schreiben und auszuführen. Das Ergebnis war gemischt.
Unter Android funktionierten einige einfache Abfragen nicht sauber, andere dagegen problemlos. Aus irgendeinem Grund funktionierte auch der REPL-Befehl nicht. Backdoor-Methoden konnte ich aber weiterhin aufrufen. Das bedeutet: Mit Einschränkungen ließ sich Xamarin.UITest zumindest unter Android noch verwenden.
Unter iOS sah es deutlich schlechter aus. Um Xamarin.UITest auf iOS zu nutzen, muss das NuGet-Paket Xamarin.TestCloud.Agent eingebunden werden, damit der Test-Cloud-Agent beim Start der App aktiv wird. Aufgrund der Tatsache, dass Xamarin.TestCloud.Agent nicht für .NET aktualisiert wurde, konnte ich es in meiner .NET-MAUI-App nicht verwenden. Ein entsprechendes Issue war bereits seit fast einem Jahr im microsoft/appcenter-Repository offen.
Weil sich App Center und insbesondere Xamarin.UITest zuletzt nur langsam weiterentwickelt haben, fordern viele Entwickler seit Längerem, Xamarin.UITest als Open Source freizugeben, in der Hoffnung, dass die Community Fehler beheben und das Projekt aktuell halten kann.
Außerdem gibt es Gerüchte, dass .NET MAUI langfristig nicht auf Xamarin.UITest setzen wird, sondern eher auf einen Appium-basierten Ansatz. Es gab zwar Versuche, neue UI-Test-Frameworks für .NET MAUI aufzubauen, etwa Maui.UITesting von @Redth oder Xappium, doch auch diese Projekte sind weitgehend eingeschlafen. Die .NET-MAUI-Mannschaft kommuniziert derzeit außerdem nicht besonders klar, wohin die Reise beim UI-Testing geht.
Alles in allem wirkt es so, als hätte UI-Testing im Moment keine besonders hohe Priorität für das .NET-MAUI-Team. Zumindest tauchte es damals nicht auf dem laufenden GitHub-Projektboard auf.
Unabhängig davon wollen wir natürlich trotzdem von automatisierten UI-Tests für .NET-MAUI-Anwendungen profitieren. Deshalb schauen wir uns jetzt an, welche Alternativen es gibt, wie sie sich im Vergleich zu Xamarin.UITest einordnen lassen und wie gut sie sich praktisch einsetzen lassen.
Ihnen gefällt, wie wir die Dinge angehen?
Dieser Blog soll Ihnen einen kleinen Einblick in unseren Arbeitsalltag geben, wenn wir eine App in einer Full-Service-Umgebung entwickeln oder unsere Expertise gezielt als EaaS einbringen.
Bevor wir auf konkrete Lösungen schauen, lohnt sich ein Schritt zurück: Was erwarten wir überhaupt von einem UI-Test-Framework für plattformübergreifende mobile Apps? Wenn es um Cross-Platform-Apps geht, möchte man in der Regel nicht mehrere Frameworks wie UIAutomator oder XCUITest separat lernen. Zumindest ich würde bevorzugen, Tests - wenn möglich - nur einmal pro Szenario zu schreiben statt einmal pro Plattform.
Welches Framework oder welche Plattform am besten zu Team und Projekt passt, hängt von vielen Faktoren ab. Manche Kriterien sind härtere Filter als andere, etwa die unterstützten Plattformen oder die verwendete Programmiersprache.
Als Entwickler liegt es nahe, auch für die UI-Tests dieselbe Sprache zu verwenden wie für die App selbst. Das ist aber nicht zwingend. In manchen Teams schreiben andere Rollen die UI-Tests, und dann kann auch ein skript- oder markup-basierter Ansatz sinnvoll sein. Textbasierte UI-Tests bringen klare Vorteile mit: Sie lassen sich gut lesen, pflegen und versionieren.
Außerdem ist nicht jede Person, die Testfälle definiert, zwingend Entwickler. Test Recorder helfen hier, aber ein echter No-Code-Ansatz kann in manchen Situationen noch besser passen.
Auch die Ausführung der Tests ist wichtig. Oft ist es vorteilhaft, Tests lokal auf Simulatoren oder physischen Geräten auszuführen. Für regelmäßige QA-Läufe will man sie aber meist direkt in CI/CD-Prozesse integrieren. Zusätzlich sollte man UI-Tests idealerweise auf einer größeren Auswahl an Geräten laufen lassen statt nur auf einigen wenigen Geräten, die man gerade zur Hand hat. Gerade im mobilen Bereich gibt es extrem viele Gerätegrößen, Auflösungen und Formfaktoren. Dafür sind Test Clouds hilfreich, denn sie ermöglichen das Testen auf vielen Geräten, ohne dass diese physisch vorhanden sein müssen.
Backdoor-Methoden sind vor allem für Entwickler interessant, weil damit App-Logik getestet werden kann, die nicht direkt über die UI erreichbar ist. Gleichzeitig sollte man dabei nicht vergessen, dass man sich damit von reinem Black-Box-Testing entfernt.
Wie man sieht, gibt es viele Eigenschaften, die ein gutes UI-Test-Framework ausmachen. Es gibt zudem unterschiedliche Ansätze, wie UI-Tests definiert werden. Jeder davon hat seine Berechtigung.
Um diese Ansätze zu repräsentieren, habe ich mich für die folgenden drei Lösungen entschieden:
Appium - ein flexibles Client-Server-Framework auf Basis des WebDriver-Protokolls
Maestro - ein neueres und besonders einfaches Framework, bei dem Tests in YAML definiert werden
Waldo - eine No-Code-Plattform, bei der Tests vor allem durch Interaktion mit einer simulierten App aufgezeichnet werden
Es gibt viele Frameworks, die auf Appium oder Selenium WebDriver aufbauen, etwa Xappium, Legerity und viele weitere. Auch umfangreichere Plattformen wie Lambdatest gehören dazu. Da sie alle stark auf Selenium oder Appium setzen, habe ich mich für diesen Vergleich auf Appium konzentriert.
Die Alternativen im Vergleich
Nach etwas Recherche und einigen Tests habe ich die folgende Tabelle erstellt, um einen schnellen Überblick darüber zu geben, wie sich die Frameworks vergleichen lassen:
Einer der größten Vorteile von Appium ist, dass es ein Open-Source-Framework mit großer Community und vielen Mitwirkenden aus ganz unterschiedlichen technischen Bereichen ist. Kein Wunder also, dass es Client-SDKs für mehrere Programmiersprachen gibt. Zusätzlich zu Android und iOS kann Appium auch Windows und Web testen und hebt sich damit von den anderen Alternativen ab. Durch die große Community und die Offenheit gibt es zudem viele ergänzende Produkte, die Test Clouds, Test Recorder oder auch Backdoor-Funktionen anbieten.
Bei Maestro werden Tests in YAML geschrieben, was den Einstieg sehr leicht macht, aber gleichzeitig die Flexibilität einschränken kann. Inzwischen gibt es mit Maestro Studio auch einen grafischen UI-Explorer, der schrittweise zu einem Test Recorder erweitert wird. Mobile.dev, das Unternehmen hinter Maestro, bietet außerdem eine eigene Test Cloud an, die zu diesem Zeitpunkt allerdings nur Tests auf Simulatoren ausführen konnte. Da Maestro ein vergleichsweise junges Framework ist, fehlt an manchen Stellen noch etwas Reife. Gleichzeitig entwickelt es sich sehr schnell weiter und bekommt regelmäßig neue Funktionen.
Waldo funktioniert anders: Tests werden nicht geschrieben, sondern über Interaktionen mit einer im Browser laufenden Simulator- oder Emulator-Session aufgezeichnet. Waldo ist im Kern sowohl Test Cloud als auch Test Recorder. Ein Nachteil ist, dass die Tests nicht lokal ausgeführt werden können, weil alles in der Cloud läuft. Das kann aber auch ein Vorteil sein, denn mit funktionierender Internetverbindung lässt sich von überall arbeiten.
Praxischeck
Bisher haben wir die Eigenschaften eher theoretisch betrachtet. Ja, UI-Tests mit Appium und Maestro können lokal ausgeführt werden. Aber wie aufwendig ist das Setup wirklich? Ein Recorder ist schön - aber wie gut lassen sich bestehende Tests danach anpassen? Und wie gut funktionieren diese Werkzeuge konkret mit .NET-MAUI-Apps?
Ich habe die Nutzbarkeit aller drei Frameworks mit einer kleinen .NET-MAUI-App auf Android und iOS getestet. Hier sind meine Eindrücke:
Appium - der Allrounder
Um UI-Tests mit Appium auszuführen, braucht man:
einen Appium-Server, also einen HTTP-Server, der Befehle von Clients entgegennimmt
einen plattformspezifischen Treiber, zum Beispiel XCUITest Driver oder UiAutomator2 Driver
einen Appium-Client oder eine passende Client-Bibliothek
Die Trennung zwischen Client und Server macht das System sehr flexibel. Der Client kommuniziert immer per HTTP mit dem Server - unabhängig davon, in welcher Programmiersprache er geschrieben wurde. Der Server interpretiert die Befehle und übersetzt sie in Kommandos für den jeweiligen Treiber. Damit kapselt er plattformspezifische Details.
So weit, so gut - allerdings steigt mit mehreren Abhängigkeiten auch die Komplexität. Einzelne Treiber benötigen zusätzliche Einrichtungsschritte. Anfang 2022 wurde Appium stark überarbeitet und auf Appium 2.0 umgestellt, wodurch viele ältere Treiber nicht mehr mit 1.x-Versionen kompatibel waren. Auch Appium Desktop, das früher eine grafische Oberfläche für die Interaktion mit dem Appium-Server bot, wurde mit dieser Umstellung eingestellt. Wenn du Appium bereits früher genutzt hast, solltest du deshalb sicherstellen, dass wirklich alles auf aktuellem Stand ist.
Beim Verbinden mit dem Appium-Server müssen Capabilities übergeben werden, die Zielplattform, Gerät, App und Treiber beschreiben. Wenn man das C#-SDK verwendet, erzeugt man typischerweise eine plattformspezifische AppiumDriver-Instanz. Anschließend lassen sich darüber UI-Elemente suchen und bedienen.
Für eine iOS-App könnte das etwa so aussehen:
var options = new AppiumOptions();
options.AddAdditionalCapability("appium:platformName", "iOS");
options.AddAdditionalCapability("appium:app", "de.cayas.mauiuitest");
options.AddAdditionalCapability("appium:udid", "4CC6A4D1-116F-4BE2-BA1B-B34805840401");
options.AddAdditionalCapability("appium:deviceName", "iPhone 14 Pro Max");
options.AddAdditionalCapability("appium:automationName", "XCUITest");
_driver = new IOSDriver<IOSElement>(new Uri("http://127.0.0.1:4723"), options);
_driver.LaunchApp();
_driver.FindElementByName("Click me").Click();
FindElementByName("Click me") funktionierte unter iOS bei mir zuverlässig. Unter Android mit dem UiAutomator2-Driver dagegen nicht. Dort musste ich stattdessen sicherstellen, dass ich AutomationId setze, um mit FindByAccessibilityId arbeiten zu können. Das zeigt: Es kann Fälle geben, in denen plattformspezifischer Testcode nötig wird.
Maestro - die einfache Variante
Maestro beschreibt sich selbst als Werkzeug, das auf Erkenntnissen aus früheren Frameworks wie Appium, Espresso, UIAutomator und XCTest aufbaut und das Testen von Android- und iOS-Apps vereinfachen soll. Verglichen mit Appium muss ich sagen: Zumindest in puncto Einstieg liefert es tatsächlich.
Alles, was du brauchst, ist die Installation der Maestro-CLI. Für iOS musst du zusätzlich sicherstellen, dass Facebooks idb-companion installiert ist. Eine Einschränkung gab es aber: Maestro konnte iOS-Apps zu diesem Zeitpunkt nur im Simulator ausführen. Unterstützung für echte iOS-Geräte war zwar angekündigt, aber noch nicht vollständig verfügbar.
UI-Tests in Maestro bestehen aus einem oder mehreren Flows, die in YAML beschrieben werden. So sah das bei meinem Test einer .NET-MAUI-App aus:
Zusätzlich kann Maestro Tests kontinuierlich neu ausführen, wenn Änderungen an der YAML-Datei vorgenommen werden. Das ist sehr praktisch, um einen Test schrittweise aufzubauen. Über Maestro Cloud lassen sich Flows außerdem in einer Test Cloud ausführen - zu diesem Zeitpunkt allerdings ebenfalls nur auf Simulatoren und Emulatoren.
Inzwischen wurde mit Maestro Studio auch ein grafischer UI-Inspector eingeführt. Kurz darauf kam eine erste Recording-Funktion hinzu, mit der sich Flows aufzeichnen lassen. Die Möglichkeiten waren zum damaligen Zeitpunkt noch eingeschränkt und unterstützten vor allem einfache Klicks, wirkten aber bereits vielversprechend.
So attraktiv das alles klingt: Es gibt natürlich auch Grenzen. Wer mit YAML arbeitet, hat nicht die Flexibilität einer vollwertigen Programmiersprache. Man ist darauf angewiesen, welche Befehle das Maestro-Team bereitstellt. Der Vorteil ist aber, dass das Team sehr aktiv entwickelt und regelmäßig neue Features ergänzt.
Waldo - die No-Code-Lösung
Wie bereits erwähnt, verfolgt Waldo einen No-Code-Ansatz. Damit das funktioniert, müssen .apk- oder .ipa-Dateien zunächst zu Waldo hochgeladen werden. Die App wird anschließend in einem Simulator oder Emulator gestartet und man wird per Browser mit einer Live-Session verbunden.
Um den ersten Test aufzuzeichnen, interagiert man einfach direkt im Browser mit der App. Nachdem alle Schritte des gewünschten Szenarios durchgeführt wurden, spielt Waldo den Test dreimal erneut ab, erstellt dabei automatisch Assertions auf Basis der UI-Veränderungen und prüft, ob der Ablauf deterministisch und wiederholbar ist.
Nach dieser Validierung kann der Test angepasst werden, zum Beispiel durch erneutes Aufzeichnen einzelner Schritte oder durch zusätzliche Assertions. Standardmäßig erwartet Waldo, dass 85 % der UI mit der ursprünglich aufgezeichneten Version übereinstimmen. Assertions können sich dabei etwa auf Textinhalte oder Positionen einzelner Elemente beziehen.
Dieser Ansatz liegt sehr nah an der realen Nutzung durch Endanwender. Gleichzeitig ist keinerlei Programmierwissen erforderlich. Der Nachteil ist, dass das Erstellen oder Anpassen von Tests dadurch auch langsam und mühsam werden kann. Man kann keine bestehenden Testbausteine leicht wiederverwenden und muss oft auf die nächste Waldo-Session warten. Außerdem gilt auch hier: Waldo führt die Tests nur auf Simulatoren aus. Dafür entfällt aber ein komplexes lokales Setup, weil alles online läuft.
Wenn Sie es bis hier geschafft haben, gehen wir davon aus, dass Sie ein gewisses Interesse an unserer Arbeit gewonnen haben. Das freut uns. Geben Sie uns gern Feedback oder sprechen Sie mit uns über Ihr Projekt.
Wir haben gesehen, dass der aktuelle Stand von Xamarin.UITest für .NET MAUI nicht mehr ausreichend ist und zugleich unklar bleibt, wohin sich UI-Testing im MAUI-Umfeld langfristig entwickelt. Es gibt unterschiedliche Wege, UI-Testing zu lösen, und jeder davon hat eigene Vor- und Nachteile. Das gilt auch für die hier vorgestellten Frameworks.
Appium ist vermutlich die funktionsreichste und flexibelste Lösung, verlangt aber mehr Setup und technisches Verständnis. Maestro überzeugt durch seine Einfachheit und ist wegen seiner schnellen Weiterentwicklung definitiv einen Blick wert. Waldo ist stark, wenn visuelle Regressionen schnell abgesichert werden sollen oder Teams ohne Programmierfokus Tests erstellen müssen.
Ich bin gespannt, welche UI-Test-Frameworks sich für .NET MAUI noch etablieren werden und ob das MAUI-Team selbst künftig eine offiziell empfohlene und wirklich kompatible Lösung für alle Zielplattformen bereitstellt. Grundsätzlich gilt schon heute: Die meisten .NET-MAUI-Apps lassen sich mit plattformspezifischen Test-Frameworks testen - vorausgesetzt, die UI-Elemente sind sauber mit AutomationId versehen.
FAQ
Die drei stärksten Alternativen sind Appium, Maestro und Waldo. Appium ist ein vielseitiger Open-Source-Allrounder, Maestro bietet einfache YAML-basierte Testdefinitionen und Waldo ist eine No-Code-Lösung für Teams ohne tiefgehende Testing-Expertise.
Ja, Appium funktioniert mit .NET MAUI-Apps auf Android und iOS. Als Open-Source-Framework mit Unterstützung für mehrere Plattformen und Programmiersprachen ist es eine der flexibelsten Alternativen zu Xamarin.UITest für automatisierte UI-Tests.
Sie können Tools wie Appium, Maestro oder Waldo verwenden, um automatisierte UI-Tests für .NET MAUI-Apps zu schreiben. Diese Tools interagieren mit der App auf UI-Ebene, simulieren Benutzeraktionen wie Tippen, Wischen und Texteingabe und prüfen, ob sich Ihre App korrekt verhält.
Maestro ist ein Mobile-UI-Testing-Framework, das einfache YAML-Dateien zur Definition von Testabläufen verwendet. Es ist auf einfache Bedienung ausgelegt und ermöglicht es Entwicklern, UI-Tests schnell und ohne komplexes Setup zu schreiben und auszuführen.
Xamarin.UITest ist nicht vollständig mit .NET MAUI kompatibel. Seit Xamarin das Ende des Supports erreicht hat, ist das Test-Ökosystem auf Alternativen wie Appium, Maestro und Waldo übergegangen, die eine bessere Kompatibilität mit .NET MAUI bieten.
Flavio Goncalves
Als Head of Technology unterstütze ich mein Team und unsere Kunden hinsichtlich neuester Technologien und Trends in der Android und iOS-Entwicklung. Unsere Projekte profitieren von meiner Xamarin und .NET MAUI-Erfahrung, sowie von meinem Faible für sauberen Code, attraktive UIs und intuitive UX. Du kannst mich gerne für einen Workshop buchen.
Kartenfunktionen sind im mobilen Bereich ein wichtiges Feature. Kaum eine App gewinnt nicht an Wert, wenn sie Karten darstellen kann. Apple und Google machen mit ihren Map-SDKs vieles richtig, aber manchmal stößt man an Grenzen - sei es aus rechtlichen Gründen oder wegen eines Bugs. In meinem Fall war Letzteres der Auslöser. Ich brauchte außerdem eine Alternative, die auch offline funktioniert.
Als Entwickler kennen wir alle das Gerücht, dass jede Art von Test teuer ist. In diesem Beitrag möchte ich einen besseren Weg zeigen, UI-Tests zu schreiben, der sogar bei großen mobilen Apps Spaß machen kann.