AppCrawler est un outil d'exploration automatisée pour applications mobiles, dont la principale caractéristique est sa flexibilité permettant de parcourir et de cliquer sur tous les éléments interactifs d'une application.
Avantages :
- Supporte Android et iOS, fonctionne sur appareils réels et émulateurs
- Permet de configurer des règles de parcours (listes noires et blanches pour améliorer la couverture)
- L'exploration en profondeur est plus complète que celle de l'outil traditionnel Monkey, car elle utilise l'arborescence DOM de l'application et clique systématiquement sur chaque élément interactif de chaque activité
- Les rapports générés incluent des captures d'écran, permettant d'identifier précisément les éléments clliqués et les résultats, facilitant ainsi le diagnostic des plantages
Inconvénients :
- Ne peut traiter qu'une seule page à la fois; pour le défilement manuel, il faut configurer des actions de défilement manuel
- Instabilité lors de l'interaction avec des applications tierces, comme par exemple l'arrêt systématique lors du téléchargement d'avatar
- Dans les zones de mise en page entièrement cliquables, certains éléments non cliquables ne sont pas explorés, comme les boutons de paramètres ou de messagerie
- Imprécision dans le ciblage des éléments sur les pages H5, où toute une zone de mise en page est considérée comme un seul bloc non cliquable
I. Configuration de l'environnement (prérequis : environnement Java installé) :
- Télécharger le dernier fichier JAR d'AppCrawler (les versions plus récentes offrent plus de fonctionnalités et une meilleure compatibilité). La version utilisée est appcrawler-2.1.0.jar. Lien de téléchargement : Baidu Yun: https://pan.baidu.com/s/1bpmR3eJ
- Appium, nécessaire pour démarrer les sessions et localiser les éléments. La version en ligne de commande est recommandée plutôt que l'interface graphique qui peut rencontrer des problèmes de mémoire. Méthode d'installation : (1) Exécuter dans le terminal : npm --registry http://registry.cnpmjs.org install -g appium (recommandé avec le miroir npm chinois) (2) Vérifier l'environnement requis pour Appium : dans le terminal, saisir appium-doctor. Si tout est correct, l'installation est réussie.
- Android SDK, principalement pour utiliser uiautomatorviewer.bat dans le dossier tools pour localiser les éléments et obtenir leurs XPath, préparatoire à la configuration.
II. Étapes d'exécution :
- Installer la dernière version de l'application sur l'appareil sans se connecter (pour éviter de manquer le contenu avant la connexion et les erreurs d'activité).
- Démarrer le service Appium Dans le terminal, saisir : appium. Le message de confirmation indique le succès du démarrage.
- Dans le dossier contenant appcrawler-2.1.0.jar, exécuter la commande suivante : Java -jar appcrawler-2.1.0.jar -a nom_application.apk -c config.yml --output repertoire_rapports/ Cela démarrera automatiquement l'application et parcourra les éléments en cliquant automatiquement. Étant donné que la profondeur d'exploration est importante, environ 496 cas de test sont exécutés, prenant généralement environ une heure. Le rapport généré automatiquement est le suivant :
**III. Rédaction du fichier de configuration config.yml (c'est le cœur de l'exécution)**Description des paramètres : Java -jar appcrawler-2.1.0.jar pour lancer AppCrawler -a suivi du nom du package d'installation (utilisé lorsque l'application n'est pas installée sur l'appareil) -c suivi du chemin et du nom du fichier de configuration personnalisé -output suivi du dossier de sortie des rapports. Si non spécifié, un dossier nommé avec l'heure actuelle est créé automatiquement
**L'essentiel réside dans la rédaction du fichier de configuration :**Le fichier de configuration suit généralement un format clé-valeur, pouvant être édité avec un éditeur de texte et renommé en .yml ou .json. Voici un exemple de fichier config.yml :
---
logLevel: "TRACE"
reportTitle: "NomProjet" # Titre affiché dans l'en-tête du rapport HTML généré (index.html)
saveScreen: true
screenshotTimeout: 20
currentDriver: "android"
showCancel: true
tagLimitMax: 5
tagLimit:
- xpath: //*[../*[@selected='true']]
count: 12
maxTime: 10800
resultDir: "" # Nom du dossier de résultats, s'il est spécifié, pas de nom dynamique
capability:
newCommandTimeout: 120
launchTimeout: 120000
platformVersion: ""
platformName: "Android"
autoWebview: "false"
autoLaunch: "true"
noReset: "true"
androidInstallTimeout: 180000
androidCapability:
deviceName: ""
appPackage: "com.nom.application"
appActivity: "" # Optionnel, l'application détermine automatiquement l'activité actuelle
dontStopAppOnReset: true
app: ""
appium: "http://127.0.0.1:4723/wd/hub"
automationName: "uiautomator2"
reuse: 3
headFirst: true
enterWebView: true
urlBlackList:
- //*[contains(@resource-id, "tv_setting_logout") and @clickable='true'] # Déconnexion
- //*[contains(@resource-id, "toolbar_close") and @clickable='true'] # Bouton de fermeture pour éviter les boucles infinies
- //*[contains(@resource-id, "login_forgot_password") and @clickable='true'] # Mot de passe oublié pour ne pas affecter la connexion
- //*[contains(@resource-id, "profile_avatar") and @clickable='true] # Avatar du profil
- //*[contains(@resource-id, "user_name") and @clickable='true] # Nom dans l'en-tête
- //*[contains(@resource-id, "company_title") and @clickable='true] # Entreprise et poste dans l'en-tête
- //*[contains(@resource-id, "company_logo") and @clickable='true] # En-tête, éviter d'entrer dans le profil
- //*[contains(@resource-id, "project_card") and @clickable='true] # Carte de projet dans les discussions
- //*[contains(@resource-id, "contact_share") and @clickable='true] # Échange de contacts dans les détails de discussion
- //*[contains(@resource-id, "profile_header") and @clickable='true] # Zone entière de l'en-tête du profil
urlWhiteList:
- //*[contains(@resource-id, "login_button") and @clickable='true'] # Bouton de connexion obligatoire
- //*[contains(@resource-id, "message_icon") and @clickable='true'] # Icône de messagerie en haut à droite
- //*[contains(@resource-id, "settings_icon") and @clickable='true'] # Bouton de paramètres en haut à gauche
backButton:
- //*[contains(@resource-id, "toolbar_back") and @clickable='true']
triggerActions: # Principalement pour résoudre les problèmes de connexion
- action: "1771019****"
xpath: "//*[@resource-id='com.nom.application:id/phone_input']"
times: 1
- action: "123456"
xpath: "//*[@resource-id='com.nom.application:id/password_input']"
times: 1
- action: "click"
xpath: "//*[@resource-id='com.nom.application:id/login_btn']"
times: 1
- action: "swipe("down")"
xpath: "//*[@resource-id='com.nom.application:id/share']"
times: 1
startupActions:
- swipe("left")
- println(driver)
testcase:
name: swipeTest
steps:
- when:
xpath: //*[contains(@resource-id, 'share')]
action: driver.swipe(0.5,0.8,0.5,0.2)
then: []
Autres paramètres importants :
1. java -jar appcrawler-2.1.0.jar --capability appPackage=xxxxxx,appActivity=xxxxxx
2. appium --session-override : Configuration pour remplacer la session existante
3. Configuration du fichier : true et false pour activer/désactiver
logLevel : Niveau de journalisation
saveScreen : Activer les captures d'écran
reportTitle : Titre du rapport
screenshotTimeout : Délai d'attente de la capture
currentDriver : Appareil actuel (Android/iOS)
resultDir : Nom du dossier de résultats
tagLimitMax : Contrôle des balises pour iOS
tagLimit : Définition des balises
maxTime : Temps d'exécution maximal
showCancel : Afficher ou non les commentaires
capability : Configuration pour Appium
androidCapability : Configuration spécifique à Android, fusionnée avec capability
iosCapability : Configuration spécifique à iOS
urlWhiteList/blackList : Listes blanches/noires
xpathAttributes : Définit les types d'attributs pour localiser les contrôles
defineUrl : Détermine l'élément pour l'URL
baseUrl : URL de départ et profondeur maximale
maxDepth : Profondeur maximale par défaut (10), combinée avec baseUrl
appWhiteList : Liste blanche d'applications
headFirst : Parcours avant ou arrière
enterWebView : Parcourir les contrôles WebView
urlBlackList : Exclure certaines pages
urlWhiteList : Seules les pages de la liste blanche sont parcourues
defaultBackAction : Action de retour par défaut
backButton : Contrôles spécifiques pour l'action de retour
firstList : Éléments prioritaires
selectedList : Liste de parcours par défaut
lastList : Derniers éléments à parcourir
blackList : Exclure certains contrôles
triggerActions : Règles définies (action, xpath, times)
autoCrawl : Capture automatique
asserts : Assertions pour déterminer l'échec
testcase : Cas de test exécutés en premier
beforeElementAction : Avant l'action sur l'élément
afterElementAction : Après l'action sur l'élément
afterUrlFinished : Après l'achèvement de l'URL
monkeyEvents : Nombre de clics Monkey
monkeyRunTimeSeconds : Durée d'exécution Monkey
given : Conditions ou entrées
when : Conditions et déclencheurs d'action
then : Assertions
4. Un ctrl+c génère le rapport, deux ctrl+c quittera le programme
5. Dans le terminal, saisir Scala pour entrer dans l'interpréteur Scala, :q ou :quit pour quitter
6. Comment régler la profondeur d'exploration pour éviter de sauter vers d'autres pages sans pouvoir revenir
7. Définir une URL de départ et maxDepth pour spécifier l'état initial et la profondeur
IV. Problèmes rencontrés et solutions
**1. Connexion :**L'application utilise une connexion par nom d'utilisateur et code. Étant donné que la page de connexion contient de nombreux boutons et icônes de vérification avec un déverrouillage par glisser-déposer complexe, la méthode par nom d'utilisateur et mot de passe a été choisie. (1) Configurer le bouton de connexion par nom d'utilisateur/mot de passe dans la liste blanche, obligatoire à cliquer, ce qui garantit d'entrer dans la page de connexion. Configuration : urlWhiteList:
- //*[contains(@resource-id, "login_credentials_btn") and @clickable='true'] # Bouton de connexion par nom d'utilisateur/mot de passe obligatoire (2) Configurer les déclencheurs pour les champs de nom d'utilisateur et de mot de passe. Lorsque ces éléments sont localisés, les informations d'identification sont saisies. Configuration : triggerActions: # Résout principalement les problèmes de connexion
- action: "177*******" xpath: "//*[@resource-id='com.nom.application:id/phone_field']" times: 1
- action: "123456" xpath: "//*[@resource-id='com.nom.application:id/password_field']" times: 1 (3) Configurer le bouton "mot de passe oublié" dans la liste noire pour éviter les opérations superflues. Configuration : urlBlackList:
- //*[contains(@resource-id, "forgot_password_btn") and @clickable='true'] # Bouton mot de passe oublié 2. Page de détail de la discussionIl s'agit d'une version en ligne de l'application. Pour éviter d'envoyer des coordonnées aux utilisateurs en ligne en cliquant sur "échanger la carte de visite", le bouton correspondant est placé dans la liste noire. 3. Page de détail de la discussionLe clic sur la carte de projet dans la page de détail de la discussion redirige vers la page du projet, provoquant une exploration répétitive. La carte de projet est donc ajoutée à la liste noire. 4. Section avatarLe clic sur l'avatar déclenche l'appareil photo, ce qui provoque l'arrêt de l'exécution. Tous les éléments cliquables liés à l'avatar sont donc placés dans la liste noire pour un fonctionnement normal.
Fin du guide, configuration terminée avec succès !