Appium Java Test Writer
Erstelle mobile Tests, die wie von einem SDET entwickelt aussehen: ein Codebase für Android und iOS, parallel sicher auf mehreren Geräten, keine sleep()-Aufrufe, Gesten, die mit java-client 9+ funktionieren, und Allure-Reports, die auf manuelle Fall-IDs verweisen. Behandelt auch die Python → Java Migration, eine häufige Aufgabe im echten Projekt, die treu und nicht nur durch bloße Übersetzung erfolgt.
Entscheide den Modus
- Manuelle Fälle → Java: Folge Workflow A.
- Python/Appium-Code → Java: Folge Workflow B. Lies zuerst
references/python-to-java-migration.md. - Framework-Grundgerüst: Generiere die Dateien aus
references/framework-scaffold.md, angepasst an die App und Plattformen des Benutzers.
Wenn der Benutzer bereits vorhandene Java-Framework-Dateien (BaseTest, eine Screen-Klasse, testng.xml, Capabilities) teilt, übernimm deren Konventionen vor den Referenzdateien.
Workflow A: Manuelle Fälle → Tests
- Normalisiere jeden Fall in: ID, Titel, Priorität, Plattform(en), Vorbedingungen, Testdaten, Schritte, erwartete Ergebnisse. Notiere plattformspezifische Schritte (Android-Zurück-Button, iOS-Berechtigungsdialog).
- Screens und Komponenten: Eine Klasse pro Screen; wiederverwendbare Widgets (Bottom Navigation, Toolbar, Bottom Sheet) als Komponentenklassen, die in Screens eingebunden werden. Screen-Methoden drücken Benutzerabsicht aus und tragen Allure
@Step("..."). Navigierende Aktionen geben das nächste Screen-Objekt zurück. - Locators – plattformübergreifend via Annotationen auf dem selben Feld:
Priorität: accessibility id → Android resource-id / iOS name → UiAutomator / iOS Predicate oder Class Chain → XPath zuletzt (langsam auf iOS, zerbrechlich überall; bei Verwendung mit Kommentar begründen). Falls keine Page Source, Appium Inspector-Ausgabe oder Screenshots bereitgestellt wurden, markiere Schätzungen mit@AndroidFindBy(accessibility = "login-button") @iOSXCUITFindBy(accessibility = "login-button") private WebElement loginButton;// TODO-VERIFY locator. Ist nur der Locator einer Plattform bekannt, schreibe diesen und lasse die andere Annotation mit einemTODO-VERIFYstehen, anstatt blind zu kopieren. - Tests: Ein
@Testpro Fall, verhaltensorientierter Methodenname,@TmsLinkmit der Fall-ID,@Epic/@Feature/@Story/@Severity(P0 → BLOCKER/CRITICAL, P1 → NORMAL, P2+ → MINOR). Datenvarianten →@DataProvidermit der Fall-ID als erster Spalte undAllure.link(caseId, "tms", caseId)im Methodenrumpf. Jedes erwartete Ergebnis wird zu einer Assertion. - Geräte-/App-Zustand: Weise auf Fälle hin, die nicht standardmäßige Capabilities benötigen (Berechtigungsdialoge benötigen
autoGrantPermissions=false, Einrichtung erfordert saubere Installation /noReset=false, emulatorspezifische Features wie Fingerabdruck) und platziere sie in einer separaten Gruppe oder notiere die Überschreibung. - Vorbedingungen: Bevorzuge Deep Links (
driver.get("myapp://cart")auf Android,mobile: deepLink) oder API-Setup vor langen Tippsequenzen. Login-Vorbedingungen nach Möglichkeit via API/Session. - Nicht automatisierbar wie beschrieben (echte SMS-OTP, echte Zahlungen, Biometrie ohne Simulatorunterstützung, subjektive visuelle Prüfungen): Liste unter "Nicht automatisiert" mit einem Alternativvorschlag (Test-OTP, Sandbox-Zahlung,
mobile: enrollBiometric/sendBiometricMatchauf Simulatoren/Emulatoren, visuelles Vergleichstool).
Workflow B: Python → Java Migration
- Lies
references/python-to-java-migration.md. - Ordne zuerst die Struktur (conftest-Fixtures → BaseTest/Factory, page-Module → Screen-Klassen,
parametrize→@DataProvider), dann übersetze den Code. - Korrigiere Anti-Patterns anstatt sie zu portieren:
time.sleep→ explizite Waits,TouchAction/MultiAction→ W3C Actions odermobile:-Gesten, desired-capabilities-dicts →UiAutomator2Options/XCUITestOptions, globaler Driver → ThreadLocal. - Behalte Testabsicht und Assertions identisch bei. Hat der Python-Test eine schwache Assertion verwendet (z.B.
assert element) oder Fehler versteckt (try/except: pass, Assertions in Bedingungen), korrigiere dies und weise in der Migrationstabelle darauf hin, da der Originaltest möglicherweise nie fehlschlagen konnte. - Gib eine Migrationstabelle aus:
Python-Datei/Funktion | Java-Klasse/Methode | Änderungen über Übersetzung hinaus.
Waits: explizit und bedingungsbasiert
- Impliziter Wait ist 0. Die Mischung von impliziten und expliziten Waits führt zu unvorhersehbaren Timeouts.
- Niemals
Thread.sleep. VerwendeWebDriverWaitmitExpectedConditions(visibilityOf,elementToBeClickable,invisibilityOf,textToBePresentInElement,attributeToBe) durch Hilfsmethoden inBaseScreen. - Warte auf das Verschwinden von Ladefehlern/Spinnern, anstatt auf Zeitablauf zu warten.
- Timeouts stammen aus der Konfiguration, nicht aus fest codierten Zahlen.
- Nach einer Aktion, die eine Liste oder ein Karussell neu rendert, warte auf ein Signal, das danach immer wahr ist (Sheet geschlossen, Loader weg, Liste vorhanden, Anzahl gleich erwartet). Warte nicht auf "erster Text geändert": der erwartete Wert könnte bereits vorhanden sein und der Wait läuft ab.
BaseScreens Wait ignoriertStaleElementReferenceException, daher erneute Abfrage innerhalb der Bedingung.
Gesten
java-client 9 hat TouchAction/MultiAction entfernt. Verwende:
- Scroll zu Element: Android
AppiumBy.androidUIAutomator("new UiScrollable(...).scrollIntoView(...)"); iOSmobile: scrollmitpredicateString. - Wischen/Ziehen/Langdrücken: Plattform-
mobile:-Gesten (Androidmobile: swipeGesture,longClickGesture; iOSmobile: swipe,touchAndHold) oder eine W3CPointerInput-Sequenz inBaseScreenfür plattformübergreifende Nutzung. Siehereferences/framework-scaffold.md→ Gestures.
Parallel Safety
Driver lebt in einem ThreadLocal<AppiumDriver>, erstellt pro Test (oder pro Klasse, falls der Benutzer nach Geschwindigkeit fragt), immer remove() nach quit(). Jedes parallele Gerät benötigt eine eigene udid und einen eindeutigen systemPort (Android) / wdaLocalPort (iOS) aus testng.xml-Parametern. Keine statischen Driver oder statischen Elementzustände.
Ausgabeformat
- Dateien: Vollständige kompilierbare Dateien mit Imports, jede unter ihrem Pfad-Überschrift. Bei mehr als ~3 Dateien oder wenn der Benutzer sie herunterladen möchte, schreibe sie auch als Projektordner auf die Festplatte.
- Rückverfolgbarkeitstabelle (Workflow A) oder Migrationstabelle (Workflow B).
- Nicht automatisiert / Lücken.
- Überprüfungsbedarf: Anzahl und Liste der
TODO-VERIFY-Locators, angenommene Capabilities (App-Pfad, Package/Activity, Bundle ID), plattformspezifische Schritte.
Halte den Text kurz; der Code ist das eigentliche Ergebnis.
Vertraulichkeit
Für Portfolio/öffentliche Arbeit verwende Package com.example (oder das des Benutzers), eine öffentliche Demo-App und ersetze Firmennamen, interne App-IDs, interne URLs, echte Telefonnummern/E-Mails oder proprietäre Ereignisnamen durch neutrale. Erwähne den Austausch in einer Zeile.
Referenzdateien
references/framework-scaffold.md: pom.xml, Konfiguration, DriverFactory mit ThreadLocal + Options-Klassen, BaseTest mit Allure-Screenshot/Page-Source bei Fehlschlag, BaseScreen mit Wait-Helpern und Gesten, testng.xml für parallele Geräte.references/python-to-java-migration.md: Gegenüberstellung von Python Appium/pytest-Idiomen zu Java/TestNG, plus eine ausgearbeitete Migration.references/example-swaglabs.md: Manuelle Fälle → Screens → Tests in der öffentlichen Sauce Labs Beispiel-App.