« Retour

Tests autos d’applis lourdes : le défi du gratuit

Vous venez du monde de Selenium, vous aimez ce framework gratuit, sa souplesse, la beauté du pattern page-object et son DSL aux petits oignons. Magnifique, mais aujourd'hui vous devez automatiser les tests d'une application lourde.

Il y a quelques années encore, choisir un outil gratuit et open-source pour ce genre de tests était un sérieux défi et présentait de nombreux risques : frameworks peu maintenus, résultats instables... Une solution propriétaire telle qu'UFT pouvait alors s'imposer comme un choix par défaut.

Est-ce différent aujourd'hui ? Nous pensons que certaines solutions sont désormais assez mûres pour être choisies au sein de projets de test ambitieux.

Pywinauto : go !

Ce nom incongru est la contraction de Python, Windows et Automation. Ce framework de test a vu le jour en 2006 (!), et donne lieu à des releases régulières depuis 2015. La version 1.0 n'est pas encore sortie (modestie de la part de Vasily Ryabov, développeur de Pywinauto ?) mais à l'utilisation, l'outil est parfaitement stable.

Avantages de Pywinauto

Utilisable dans tout IDE Python, la solution permet à l'utilisateur d'architecturer les projets de tests comme bon lui semble. Nous avons opté pour le pattern page-object, un grand classique qui permet de maintenir facilement les tests.

Principes

Identification des objets pour Pywinauto

L'identification des objets d'application Windows peut se faire grâce à des outils comme Inspect.exe, fourni avec le SDK Windows. UI Spy peut aussi être envisagé, mais il n'est plus maintenu par Microsoft. Cependant, à l'usage, nous l'avons trouvé plus rapide.

Grâce à ces utilitaires, il est possible de connaître les paramètres des objets, et donc de les identifier pour interagir avec eux (voir la liste des paramètres gérés par Pywinauto).

Interaction avec les objets avec Pywinauto

Dans l'exemple ci-dessous, nous déclarons ainsi une page ainsi que quelques objets, en utilisant au besoin plusieurs paramètres.

class AccueilPage:

    def __init__(self, test):
        self.ECRAN_ACCUEIL = test.app.window(title='Ma super appli - Accueil')
        self.INPUT_NOM = self.ECRAN_ACCUEIL.child_window(control_type="Edit", auto_id='23', found_index=0)
        self.INPUT_PRENOM = self.ECRAN_ACCUEIL.child_window(control_type="Edit", auto_id='24', found_index=0)

Dans l'architecture que nous avons mise en place, un test doit être invoqué au moment de l'appel du constructeur de la page. Ce test est initialisé au début de chaque scénario et correspond à la classe suivante :

class Test:
    app = Application(backend='uia')

    def __init__(self):
        parser = argparse.ArgumentParser()
        parser.add_argument("--log", help="enable logging", type=str, required=False)
        args = parser.parse_args()

        actionlogger.enable()
        logger = logging.getLogger('pywinauto')
        if args.log:
            logger.handlers[0] = logging.FileHandler(args.log)

        self.app = Application(backend='uia').start(r'C:\chemin\vers\ma\super\appli.EXE')

Selon la façon dont l'application a été développée, certains objets ont un titre qui est affiché dans l’arborescence, ici d'UI Spy :

Dans cet exemple, on peut interagir avec le bouton « Appliquer » en utilisant le mot-clé title :

test.app.window(title='Appliquer')

Points d'attention

Certains objets complexes, par exemple des cellules de tableaux spécifiques, n'apparaissent pas toujours dans l'arborescence. Ce n'est pas nécessairement un problème provenant de Pywinauto, mais il faut garder en tête des solutions de contournement, par exemple la reconnaissance d'image que l'on trouve entre autres avec Sikulix.

Verdict

De notre côté, c'est un go ! Pywinauto a toute sa place au sein d'un POC, et a en outre l'avantage d'avoir un support efficace. Vasily Ryabov est très réactif sur Github aussi bien que sur StackOverflow, ce qui permet d'aller au-delà des blocages éventuels.

Winium : no go !

Framework basé sur Selenium et adapté aux applications Windows, la promesse de Winium est (était) séduisante... Malheureusement, il n'est plus maintenu et certains bugs empêchent de s'en servir efficacement. Nous vous expliquons cependant ce qui nous a plu et déplu dans cet outil, qui reste une excellente initiative.

Avantages de Winium

Pour un habitué de Selenium, la transition se fait en douceur ; les mêmes méthodes peuvent être utilisées dans la plupart des cas.

Vous ne rêvez pas ! On dirait bien un test Selenium...

Problèmes rencontrés

Identification des éléments

Afin d'interagir avec les objets de l'application à tester, plusieurs méthodes sont possibles (mais moins que pour Pywinauto). De la plus à la moins robuste, on peut procéder :

  • Par Id
  • Par Name
  • Par ClassName
  • Par Xpath

Les trois premiers paramètres, que l'on peut trouver avec les outils mentionnés précédemment, sont les plus pratiques à utiliser. Malheureusement, ils ne sont pas toujours renseignés. Il faut  alors avoir recours à la recherche par xPath, ce qui peut être plus difficile dans ce contexte que dans celui d'un DOM HTML.

Quelle que soit la méthode utilisée, les éléments semblent être trouvés d'autant plus lentement que l'interface compte un grand nombre d'objets.

Comme solution de contournement pour accélérer le test, nous avons utilisé Sikulix, avec toutes les questions que cela soulève côté maintenance.

Bug de focus

Nous avons relevé un bug assez ennuyeux : il arrive que l'application cible ne reçoive pas le focus pendant les tests. Pour peu que la fenêtre de l'IDE soit affichée, on se retrouve à taper l'identifiant en lieu et place du script de test.

A part fermer les fenêtres inutiles et réduire la fenêtre de l'IDE après le lancement de la campagne, nous n'avons pas trouvé de solution à ce problème.

Des nouvelles du créateur de Winium

Les logiciels ne poussent pas dans les arbres, en l'occurrence Winium est la création de Nick Abalov, actuellement développeur chez Badoo. Sur Twitter, il a gentiment répondu à notre question "Winium est-il mort ?" :

For Windows Desktop automation you might want to look into https://t.co/2agvjg2Kdj

— Nick Abalov (@NickAb) 20 décembre 2018

<script>

A suivre alors, WinAppDriver présentant cependant la contrainte de nécessiter un environnement Windows 10.

Verdict

Pour nous, c'est donc un no-go. Il est possible de mettre en place de petits projets d'automatisation en utilisant Winium, mais entamer un projet ambitieux avec cet outil serait imprudent.

Et vous, quels frameworks gratuits d'automatisation d'applications lourdes utilisez-vous ?

Un avis ? Un commentaire ?

Cet espace est pour vous.