.
11 mai, 2020 – 8 min de lecture
L’automatisation des tests d’interface utilisateur sur iOS est devenue aussi facile que d’écrire des tests unitaires depuis qu’Apple a introduit le framework XCUI. Dans ce post, je vais parler de la façon dont XCUI, couplé à la conception en couches, peut aider à automatiser facilement les applications, en particulier celles avec de multiples éléments d’interface utilisateur personnalisés. L’une de ces applications où nous l’avons largement utilisé est VMware Boxer, une application d’entreprise de VMware qui regroupe trois fonctions importantes – Email, Calendrier et Contacts. VMware Boxer utilise plusieurs types d’éléments d’interface utilisateur, de l’UITableView natif aux éléments visuels hautement personnalisés.
Il est supposé que les lecteurs ont une compréhension de base de Xcode, Objective C, Swift, du framework XCUI et de l’écosystème de développement Apple en général. Si vous êtes nouveau à XCUI, vous devriez d’abord commencer ici.
Comme tout autre projet d’automatisation de l’interface utilisateur, notre équipe a commencé par une question sur le cadre d’automatisation à utiliser. Nous avions utilisé SeeTest. Cependant, nous y avons vu l’occasion de revoir notre stratégie d’automatisation compte tenu de la nouvelle fonctionnalité complexe ajoutée dans VMware Boxer, du nombre de produits dans l’écosystème VMware et des tests d’intégration entre ces produits. Voici les choix que nous avons envisagés-
1. Continuer avec SeeTest
2. Earl Grey
3. XCUI
Alors que SeeTest avait la capacité de gérer nos besoins immédiats d’automatisation, il y avait un défi indépendant à gérer. Il nous fallait adopter une nouvelle pile technologique. Cela nécessiterait une formation supplémentaire pour les développeurs iOS et des experts dédiés pour maintenir le système d’automatisation.
Que dire d’Appium ? Nous n’avons pas envisagé Appium pour les mêmes raisons que celles mentionnées ci-dessus pour SeeTest. Appium est un bon choix si nous avions des applications hybrides ou un code partagé important entre Android et iOS.
Earl Grey 1 était un choix possible, étant donné qu’il nous permettait de rester dans Xcode et les outils de développement d’Apple et qu’il était basé sur XCTest. Cependant, l’automatisation Earl Grey 1 s’exécute dans le même processus que l’application testée. En revanche, l’automatisation basée sur le framework XCUI d’Apple s’exécute dans un processus distinct de celui de l’application testée. Ceci est préférable puisque l’application sous test ne devrait être rien de plus qu’une boîte noire pour l’entité (un processus d’automatisation ou un utilisateur final) qui teste son interface utilisateur.
Avoir le processus d’automatisation (celui qui teste) isolé de l’application réelle sous test. L’application sous test ne devrait être rien de plus qu’une boîte noire pour le processus d’automatisation.
Tout nouvel outil dans l’écosystème Apple qui n’est pas aligné sur l’approche d’Apple (par exemple Earl Grey 1) peut échouer sans avertissement. Une telle approche peut nécessiter beaucoup d’efforts de maintenance pour continuer à fonctionner avec des offres plus récentes ou futures d’Apple.
L’Earl Grey 2 a ajouté la capacité d’interagir avec XCUI. C’était une tentative d’alignement avec XCUI mais il avait ces problèmes connus.
Enfin, XCUI a été le choix préféré. Avec cela, un développeur aura plus de contrôle sur l’automatisation et sera le bénéficiaire immédiat de toute innovation dans l’écosystème d’Apple.
Application sous test et module d’automatisation XCUI
Avant de sauter dans les détails, il est important de répéter que le module d’automatisation utilisant XCUI s’exécute comme un processus indépendant de l’application qui est sous test. Pour commencer, nous avons ajouté un nouveau module que nous appellerons désormais le module d’automatisation (AM). AM est un espace de travail contenant une collection de classes et de structures de données utilisées pour l’automatisation de VMware Boxer à l’aide de XCUI.
Identifiants d’accessibilité
Il est important que l’application soit développée en gardant à l’esprit sa testabilité. L’une des responsabilités du développeur est de s’assurer que chaque élément de l’interface utilisateur qui est exposé à l’utilisateur final a l’identifiant d’accessibilité défini pendant le développement. L’identifiant d’accessibilité est le lien entre l’application en cours de test et le processus d’automatisation XCUI.
L’identifiant d’accessibilité est le lien entre l’application en cours de test et le processus d’automatisation XCUI.
Design Pattern
Comme mentionné précédemment, VMware Boxer est une application énorme. Le choix du patron de conception à utiliser est arrivé en gardant à l’esprit que les tests doivent être faciles à mettre en œuvre, faciles à maintenir, réutilisables, robustes et évolutifs. Le contenu ci-dessous explique les couches de l’architecture du module XCUI Automation pour VMware Boxer :
La figure suivante montre les blocs de construction de base :
Tests Classes
C’est la couche qui a les classes ayant les méthodes de test. L’intention de cette couche est d’avoir des tests comprenant un code minimal qui dit seulement ce qui est testé. De plus, le développeur qui implémente les tests doit seulement penser au flux d’application de haut niveau nécessaire pour tester ce qui est testé. Le reste de la complexité (par exemple, comment naviguer vers l’interface utilisateur où les tests souhaités peuvent être effectués) doit être abstrait dans des couches réutilisables. Référez-vous à l’image ci-dessous qui montre un exemple de méthode de test expliquant l’intention ci-dessus – le code teste si une IU de paramètres peut aider à activer/désactiver une fonctionnalité ou si elle a des contrôles de commutateur requis.
Ainsi, le développeur qui écrit les tests pourrait écrire un code aussi simple que le pseudo-code. En attendant, il est clair qu’une certaine logique doit être invoquée à partir de la couche suivante (Flows : expliqué dans la section suivante).
Flows Classes
Les Flows représentent une collection de classes qui fournit les fonctionnalités requises pour diverses classes de Tests. Les fonctionnalités peuvent inclure la configuration de l’app avant l’exécution du cas de test réel ou la navigation vers une certaine partie de l’app testée. La plupart de ces fonctionnalités sont réutilisables et requises dans de multiples tests. Par exemple, l’exemple de scénario de test ci-dessus requiert que 1. l’application soit lancée et 2. que l’application soit activée. Nous naviguons vers un écran de paramètres du Feature Controller.
Donc, les classes de flux seraient invoquées à partir des tests et mettraient en œuvre des flux comme « Naviguer vers les paramètres » ou « Naviguer vers les paramètres du Feature Controller ».
Classes d’écrans
Les écrans sont des classes qui ont un mappage un à un avec les View Controllers respectifs. Un contrôleur de vue peut être, à haut niveau, vu comme une classe ayant (dans la vue arrière) des UIControls et des méthodes qui répondent à l’interaction de l’utilisateur avec ces UIControls. Une classe Screen est simplement un mappage proxy du View Controller. La figure ci-dessous illustre ce mappage. Il y a une cellule Vue initiale dans l’interface utilisateur et lorsque l’utilisateur tape sur cette cellule, il peut sélectionner ce qui doit être marqué comme la vue initiale de l’application. La figure ci-dessous montre comment une classe Screen est mise en œuvre pour mettre en correspondance l’exigence ci-dessus.
Le pseudo-code pour cette classe Screen ressemblerait à –
// The class models the SettingFormViewController for XCUI tests.public class SettingsFormScreen {
private static let navBarId = "Boxer.Settings.NavigationBar"
private lazy var featureControllerCell = boxerApp.application.tables.cells public func navigateToFeatureController() -> Bool {
return // tap on Cell with featureControllerCellId
}
}class AccessibilityIdentifiers: NSObject {// MARK: Settings Screenstatic let featureControllerCellId = "Boxer.Settings.FeatureControllerCell"
}
qu’est-ce que boxerApp dans le code ci-dessus ? Dans le code ci-dessus boxerApp représente une unité qui est une instance de la classe BoxerApp qui encapsule l’application sous test et ses écrans. Ceci est expliqué dans la section suivante.
Le code ci-dessus modélise le SettingFormViewController de VMware Boxer. La convention utilisée pour nommer la classe est que le nom est dérivé du nom du contrôleur de vue en remplaçant le suffixe ViewController par Screen. Notez également la classe de commodité qui a des identifiants d’accessibilité.
L’identifiant d’accessibilité est le lien commun entre l’application sous test et le processus d’automatisation XCUI.
Putting it Together : Module d’automatisation VMware Boxer XCUI
Le module UITest teste l’application en cours d’exécution. Il est important que le modèle d’application soit conçu de telle sorte qu’une instance de l’app testée soit une unité unique. Cela signifie que l’application sous test doit être vue comme une collection de classes d’écrans participant à des flux d’affaires (collection de classes de flux)qui sont invoqués à partir des tests (collection de classes)en fonction de l’exigence du test. Chaque unité d’application devrait avoir exactement une instance de chaque classe d’écran qui correspond à un contrôleur de vue.
Comment réaliser cela ?
Une suite de test XCUIT peut réaliser cela en encapsulant l’instance de l’application sous test(XCUIApplication) dans une unité par exemple la classe BoxerApp qui a une application membre et a tous les écrans pour cette application. La figure ci-dessous explique cette encapsulation
Par conséquent, avant que la suite XCUITest ne démarre, la première chose qu’elle ferait serait de créer une instance du module BoxerApp en utilisant l’identifiant de bundle de l’application sous test. La figure ci-dessous explique cela