Les objets d'interface graphique sont présentés dans deux hiérarchies liées : parent-enfant et possesseur-possédé. Une boîte de dialogue et un bouton figurant dans la boîte de dialogue présentent une relation parent-enfant. Une fenêtre de niveau supérieur et une boîte de dialogue présentent une relation possesseur-possédé. Vous pouvez utiliser n'importe quel type de hiérarchie pour un objet.
Dans une implémentation de proxy, le modèle d'objet sous-jacent (par exemple Java™ et HWND) confond souvent ces deux relations et traite la relation possesseur-possédé comme une relation parent-enfant asymétrique. Dans ce cas, le proxy doit nier le fait qu'il possède un parent lorsque le modèle de relation préférable est possesseur/possédé. Les méthodes permettant de parcourir la hiérarchie sont getParent(), getChildren(), getOwner() et getOwned().
Les propriétés sont des valeurs nommées. La propriété elle-même n'est pas associée à un type ; c'est la valeur qui possède un type. Evitez le renvoi par les proxys de types différents pour la même propriété. Parfois, une valeur de propriété peut être une référence à un objet plutôt qu'une valeur. Si une telle valeur est renvoyée à un script, elle est renvoyée sous forme d'objet de test (TestObject). Les méthodes d'accès aux propriétés sont getProperty(), setProperty(), getProperties() et getNonValueProperties().
Par défaut, il se peut que les nouveaux objets de proxy ne soient pas associés à des propriétés de reconnaissance ni à des poids. Utilisez la bibliothèque d'objets pour affecter les propriétés de reconnaissance et les poids. Les méthodes d'accès aux propriétés de reconnaissance et aux poids des objets sont getRecognitionProperties() et getRecognitionPropertyWeight(). Si plusieurs objets de la même classe existent dans l'objet parent, ajoutez la propriété .classIndex (valeur numérique positive à partir de 0) en tant que propriété de reconnaissance pour l'objet enfant.
En général, l'intégralité de la hiérarchie des objets est mappée. Toutefois, certains objets peuvent changer fréquemment d'une génération de l'application de test à l'autre. Par exemple, dans Java, il est fréquent d'ajouter des panneaux afin de regrouper des objets. Avec Functional Tester, l'utilisateur peut spécifier qu'il ne souhaite pas mapper l'objet de proxy. Même si les objets qui ne sont pas mappables ne se trouvent pas dans la mappe d'objets de test, ils sont répertoriés dans la hiérarchie des objets lorsque vous parcourez la hiérarchie parent-enfant. Les méthodes de gestion de la hiérarchie mappable sont shouldBeMapped(), getMappableParent() et getMappableChildren().
Dans certains cas, le modèle d'objet sous-jacent prend en charge une notion de propriétés, par exemple Java, HTML et .NET. Functional Tester permet aux proxys d'implémenter des propriétés supplémentaires. Si un proxy implémente une propriété directement, le modèle de nom de la propriété doit être différent afin d'éviter la confusion avec une autre propriété de l'objet. Les noms de propriété standard susceptibles d'être utilisés pour la reconnaissance doivent commencer par un point (.). Certaines propriétés d'administration sont utilisées par la structure et ne peuvent pas être utilisées pour la reconnaissance : leurs noms doivent commencer par le signe dièse (#).
Dans de nombreux cas, l'objet sous-jacent comporte des méthodes pouvant être recherchées et appelées. Elles sont généralement gérées directement par la structure et l'implémentation de domaine, mais la méthode getMethod() est communément implémentée sur un proxy de base dans un domaine.
Si possible, faites en sorte que les actions de la souris soient lues à partir d'une méthode dont le nom reflète l'action. Si un nom de méthode inclut le terme "click" ou "drag", l'action doit être effectuée par des événements de souris. N'utilisez pas de noms de méthode tels "click" ou "drag" si des événements de souris ne sont pas utilisés pour implémenter l'action. N'utilisez pas de noms de méthode référençant les touches ou le clavier si l'action n'est pas implémentée par des événements de clavier. Faites en sorte que les méthodes reflètent l'action à exécuter et qu'elles soient fiables pendant la lecture. Evitez les méthodes heuristiques.
Les objets peuvent contenir d'autres objets et posséder une structure interne qui ne se présente pas sous forme d'un ou de plusieurs objets imbriqués. Par exemple, une liste peut se composer d'éléments, mais les éléments ne sont pas forcément présentés par l'objet de liste sous forme d'objets. Ce type de comportement est fréquent dans le cas des objets reposant sur HWND. Les méthodes de traitement des sous-éléments les plus courantes sont getSubitem() et les méthodes d'action de la souris telles click(), drag() et doubleClick(). La méthode getSubitem() renvoie une valeur null ou une chaîne.
Utilisez l'une des stratégies suivantes si vous ne voulez pas que les objets figurant dans les sous-éléments soient présentés sous forme d'objets à part entière :
Déclarez que le proxy de sous-élément n'est pas mappable. L'objet sélectionné communique avec son parent et il incombe au proxy du parent d'enregistrer les actions pour l'objet agrégé et de prendre en charge la lecture des actions d'interface graphique reposant sur le sous-élément.
Lors de l'enregistrement, le proxy du sous-élément transmet les appels processMouseEvent() à son parent. Il incombe au proxy du parent d'enregistrer les actions pour l'objet agrégé et de prendre en charge la lecture des actions d'interface graphique reposant sur le sous-élément.
Lors de l'enregistrement, le proxy du sous-élément traite des appels processMouseEvent() et génère les appels de méthode sur l'objet parent. Il n'incombe pas au proxy du parent d'enregistrer les actions pour l'objet agrégé mais il lui revient de prendre en charge la lecture des actions d'interface graphique reposant sur le sous-élément.
Définissez un nouveau type de référence d'objet balisée de sorte que l'enregistrement de la référence soit annulé une fois la référence utilisée comme ancre. Cette opération permet d'ancrer un objet avec les sous-éléments d'un autre objet. Vous pouvez mapper l'objet imbriqué en tant qu'enfant de l'objet parent.
Respectez les règles suivantes lors de l'implémentation des exceptions et des erreurs :
N'émettez pas d'exceptions privées ou internes à partir des proxys. Il se peut que la documentation de l'API de vos proxys ne soit pas disponible. Utilisez des exceptions standard, de préférence des exceptions de test Rational.
Réutilisez les exceptions provenant du module com.rational.test.ft dans Java ou de l'espace de nom Rational.Test.Ft dans .Net. Si un proxy Java émet une exception com.rational.test.ftMethodNotFoundException et que le script est écrit en VB, le script VB reçoit une exception Rational.Test.Ft.MethodNotFoundException. Si vous émettez une exception dont le nom ne commence pas par com sous com.rational.test.ft, elle est convertie en exception WrappedException.
Toutes les exceptions de test Rational dont les paramètres peuvent être convertis doivent prendre en charge un constructeur associé à un paramètre de chaîne unique.
Si vous ajoutez une nouvelle exception dans un proxy implémenté en Java qui doit pouvoir être renvoyé au client, assurez-vous d'implémenter la même exception dans .Net.
Dans Java, certaines exceptions qui ne sont pas forcément utiles à certains testeurs doivent être déclarées. De nombreuses exceptions proviennent de virtuellement n'importe quelle méthode d'interface utilisateur ; par conséquent, utilisez des exceptions d'exécution à la place d'exceptions dans Java. Evitez d'utiliser des erreurs. Une erreur arrête la session de lecture ou de l'enregistreur.
Si l'objet est introuvable, la structure émet une exception ObjectNotFoundException. Si l'objet est trouvé mais qu'un sous-élément spécifié est introuvable, le proxy doit émettre une exception SubItemNotFoundException. L'exception SubItemNotFoundException est détectée par la structure, qui fait une nouvelle tentative automatiquement.
Si les coordonnées entrées entraînent le clic d'un objet ou d'un sous-élément au-delà de la région, modifiez les coordonnées de sorte qu'elles incluent la région de l'objet ou du sous-élément. Ajoutez un mécanisme permettant de générer un avertissement dans le journal si une telle situation se produit. Le proxy peut être amené à utiliser des clics reposant sur des coordonnées si l'agencement de l'écran objet ne peut pas être décrit complètement. Par exemple, dans un objet JTree, la géométrie PLUS_MINUS est inconnue, mais elle peut être relative au sous-élément auquel elle s'applique. Le proxy peut étendre la zone du sous-élément afin d'inclure la géométrie PLUS_MINUS. Vous pouvez utiliser des coordonnées négatives pour les sous-éléments. Documentez toutes les violations du comportement normal. Assurez-vous qu'aucun sous-élément associé à un clic reposant sur des coordonnées spécifiques n'entraîne un clic hors de l'objet.
Si l'utilisateur clique sur un objet inapproprié, émettez une exception com.rational.test.ft.CoordinateOnWrongObjectException. Il se peut que l'objet inapproprié chevauche la cible correcte. Vous pouvez changer les coordonnées afin d'éviter l'objet enfant dans un conteneur. Ignorez le point spécifié et recherchez un autre point sur l'objet approprié à cliquer. Evitez d'enregistrer des coordonnées pour des objets possédant des enfants mappables et n'autorisez pas les clics d'objets inappropriés.
Si l'utilisateur clique sur un sous-élément inapproprié, émettez une exception com.rational.test.ft.CoordinateOnWrongSubitemException. Cette exception n'est pas valable pour les clics associés à un objet pour lequel aucun sous-élément n'est spécifié. Ce type de clic s'applique uniquement lorsque l'utilisateur clique sur l'objet et l'un des sous-éléments de cet objet. Dans ce cas, le sous-élément inapproprié chevauche la cible correcte et est probablement un enfant. Pour éviter cette exception, n'enregistrez pas les coordonnées de sous-éléments possédant des sous-éléments imbriqués. Ignorez le point spécifié et recherchez un autre point sur un sous-élément approprié à cliquer.