Appium Java Test Writer - Rédacteur de Tests Appium Java
Produisez des tests mobiles qui semblent avoir été écrits par un SDET professionnel : une seule base de code pour Android et iOS, compatible parallélisation entre appareils, sans sleep, avec des gestes fonctionnant sur java-client 9+, et des rapports Allure qui tracent les identifiants des cas de test manuels. Cette compétence gère également la migration Python → Java, une tâche courante dans le monde réel qui mérite d'être réalisée fidèlement (et pas simplement translittérée).
Déterminez le mode
- Cas manuels → Java : suivez le Workflow A.
- Code Python/Appium → Java : suivez le Workflow B. Lisez d'abord
references/python-to-java-migration.md. - Générer un framework : créez les fichiers à partir de
references/framework-scaffold.md, adaptés à l'application et aux plateformes de l'utilisateur.
Si l'utilisateur partage des fichiers de framework Java existants (BaseTest, une classe d'écran, testng.xml, capabilities), adoptez leurs conventions plutôt que celles de référence.
Workflow A : cas manuels → tests
- Normalisez chaque cas en : ID, titre, priorité, plateforme(s), préconditions, données de test, étapes, résultats attendus. Notez les étapes spécifiques à une plateforme (bouton retour Android, alerte de permission iOS).
- Écrans et composants : une classe par écran ; les widgets réutilisables (barre de navigation inférieure, barre d'outils, feuille inférieure) en tant que classes de composants intégrées aux écrans. Les méthodes des écrans expriment l'intention de l'utilisateur et portent l'annotation Allure
@Step("..."). Les actions de navigation retournent l'objet de l'écran suivant. - Localisateurs — multiplateforme via des annotations sur le même champ :
Priorité : accessibility id → Android resource-id / iOS name → UiAutomator / iOS predicate ou class chain → XPath en dernier (lent sur iOS, fragile partout ; commentez pourquoi s'il est utilisé). Si aucune source de page, sortie Appium Inspector ou capture d'écran n'a été fournie, marquez les suppositions@AndroidFindBy(accessibility = "login-button") @iOSXCUITFindBy(accessibility = "login-button") private WebElement loginButton;// TODO-VERIFY locator. Si le localisateur d'une seule plateforme est connu, écrivez celui-ci et laissez l'autre annotation avec unTODO-VERIFYplutôt que de le copier aveuglément. - Tests : un
@Testpar cas, méthode nommée d'après le comportement,@TmsLinkavec l'ID du cas,@Epic/@Feature/@Story/@Severity(P0 → BLOCKER/CRITICAL, P1 → NORMAL, P2+ → MINOR). Variantes de données →@DataProvideravec l'ID du cas comme première colonne etAllure.link(caseId, "tms", caseId)dans le corps. Chaque résultat attendu devient une assertion. - État de l'application/du périphérique : signalez les cas nécessitant des capacités non par défaut (les boîtes de dialogue de permission ont besoin de
autoGrantPermissions=false, l'intégration nécessite une installation propre /noReset=false, les fonctionnalités propres à l'émulateur comme l'empreinte digitale) et placez-les dans un groupe séparé ou notez la substitution. - Préconditions : privilégiez les liens profonds (
driver.get("myapp://cart")sur Android,mobile: deepLink) ou la configuration via API plutôt que de longues séquences de tapotements. Les préconditions de connexion via API/session lorsque c'est possible. - Non automatisable tel qu'écrit (OTP SMS réel, paiements réels, biométrie sans support simulateur, vérifications visuelles subjectives) : listez sous « Non automatisé » avec une alternative (OTP de test, paiement en sandbox,
mobile: enrollBiometric/sendBiometricMatchsur simulateurs/émulateurs, outil de comparaison visuelle).
Workflow B : migration Python → Java
- Lisez
references/python-to-java-migration.md. - Cartographiez d'abord la structure (fixtures conftest → BaseTest/factory, modules de page → classes d'écran,
parametrize→@DataProvider), puis traduisez le code. - Corrigez les anti-patrimoines au lieu de les porter :
time.sleep→ attentes explicites,TouchAction/MultiAction→ Actions W3C ou gestesmobile:, dictionnaires desired-capabilities →UiAutomator2Options/XCUITestOptions, driver global → ThreadLocal. - Gardez l'intention du test et les assertions identiques. Si le test Python assertait quelque chose de faible (par ex.
assert element) ou masquait les échecs (try/except: pass, assertions dans des conditionnelles), corrigez-le et signalez-le dans le tableau de migration, car le test original n'a peut-être jamais pu échouer. - Produisez un tableau de migration :
Fichier/fonction Python | Classe/méthode Java | Changements au-delà de la traduction.
Attentes : explicites et basées sur des conditions
- L'attente implicite est 0. Mélanger des attentes implicites et explicites provoque des délais d'attente imprévisibles.
- Jamais de
Thread.sleep. UtilisezWebDriverWaitavecExpectedConditions(visibilityOf,elementToBeClickable,invisibilityOf,textToBePresentInElement,attributeToBe) via des helpers dansBaseScreen. - Attendez que les chargeurs/spinners disparaissent plutôt que de laisser passer le temps.
- Les délais d'attente proviennent de la configuration, pas de nombres en dur.
- Après une action qui réaffiche une liste ou un carrousel, attendez un signal qui est toujours vrai par la suite (feuille fermée, chargeur disparu, liste présente, compte égal à l'attendu). N'attendez pas « le texte du premier élément a changé » : la valeur attendue peut déjà être en place et l'attente expire. Le wait de BaseScreen ignore
StaleElementReferenceException, donc interrogez à nouveau dans la condition.
Gestes
java-client 9 a supprimé TouchAction/MultiAction. Utilisez :
- Défiler jusqu'à un élément : Android
AppiumBy.androidUIAutomator("new UiScrollable(...).scrollIntoView(...)"); iOSmobile: scrollavecpredicateString. - Balayage/glisser/appui long : gestes
mobile:de la plateforme (Androidmobile: swipeGesture,longClickGesture; iOSmobile: swipe,touchAndHold) ou une séquence W3CPointerInputdansBaseScreenpour une utilisation multiplateforme. Voirreferences/framework-scaffold.md→ Gestes.
Sécurité parallèle
Le pilote vit dans un ThreadLocal<AppiumDriver> créé par test (ou par classe si l'utilisateur demande de la rapidité), toujours remove() après quit(). Chaque appareil parallèle a besoin de son propre udid et d'un systemPort (Android) / wdaLocalPort (iOS) unique, provenant des paramètres testng.xml. Pas de pilotes statiques ni d'état statique des éléments.
Format de sortie
- Fichiers : fichiers complets compilables avec imports, chacun sous son en-tête de chemin. Si plus de ~3 fichiers ou si l'utilisateur souhaite les télécharger, écrivez-les également sur le disque sous forme de dossier de projet.
- Tableau de traçabilité (Workflow A) ou tableau de migration (Workflow B).
- Non automatisé / lacunes.
- Nécessite une vérification : comptez et listez les localisateurs
TODO-VERIFY, les capacités supposées (chemin de l'application, package/activity, bundle id), les étapes spécifiques à une plateforme.
Gardez le texte concis ; le code est le livrable.
Confidentialité
Pour un travail de portfolio/public, utilisez le package com.example (ou celui de l'utilisateur), une application de démonstration publique, et remplacez les noms d'entreprise, les identifiants d'application internes, les URL internes, les numéros de téléphone/e-mails réels ou les noms d'événements propriétaires par des termes neutres. Mentionnez le remplacement en une ligne.
Fichiers de référence
references/framework-scaffold.md: pom.xml, config, DriverFactory avec ThreadLocal + classes Options, BaseTest avec capture d'écran Allure/source de page en cas d'échec, BaseScreen avec helpers d'attente et gestes, testng.xml pour les appareils parallèles.references/python-to-java-migration.md: mappage côte à côte des idiomes Python Appium/pytest vers Java/TestNG, plus une migration complète.references/example-swaglabs.md: cas manuels → écrans → tests sur l'application exemple publique Sauce Labs.