L'hyper automatisation des tests logiciels grâce à l'intelligence artificielle

Tests de logiciels

De nos jours, les sociétés évoluent à un rythme rapide. Ces évolutions impliquent des changements dans nos outils. C'est le cas des logiciels, ils doivent évoluer et rester à jour pour répondre à nos besoins. Mais, comment s'assurer que les logiciels répondent à nos besoins malgré l'évolution ? Un moyen populaire et efficace est le test. Un test permet de vérifier le comportement d'un logiciel afin de détecter d'éventuels bogues et de s'assurer qu'il correspond aux attentes. Dans cet article, nous allons nous concentrer sur les tests fonctionnels avant la mise en production d'un logiciel. Ces tests sont réalisés à l'aide de différents scénarios qui sont composés de séquences. Lorsque la séquence arrive à son terme, elle produit une valeur ajoutée métier qui est comparée à l'attente du testeur.

Lorsqu'un logiciel est composé de différents composants logiciels, il est humainement impossible de mettre en place des tests car le nombre de scénarios est trop important du fait des interactions des différents composants, donc tous les scénarios ne sont pas testés. Un autre point important est le coût de maintenance pour maintenir le logiciel à jour. C'est pourquoi les chercheurs ont essayé d'automatiser une partie de ces tests. Comme vous pouvez le voir sur la page figure 1L'automatisation a permis de réduire considérablement les coûts de maintenance dans le temps.

Figure 1 : Coût de maintenance des tests manuels et automatisés
Figure 1 : Coût de maintenance des tests manuels et automatisés

Les derniers progrès de l'Intelligence Artificielle offrent de nouvelles opportunités à l'hyper automatisation des tests. L'objectif est de créer un système logiciel générique presque autosuffisant capable de vérifier le comportement d'un logiciel. Pour fonctionner, le testeur de systèmes logiciels devra être composé de différentes données. (figure 2):
A. Un logiciel à tester,
B. Séquences d'actions à réaliser. Ces actions seront des données à saisir par le logiciel de test,
C. Données contextuelles et techniques décrivant l'environnement dans lequel évolue le logiciel testé,
D. Un état référentiel (conforme à l'attente),
E. Un testeur capable de comparer l'état du résultat du test avec l'état référentiel pour interpréter le résultat et donner un verdict.
Il s'agit d'un objectif ambitieux puisque l'intelligence artificielle devrait générer de manière indépendante toutes les données énumérées au lieu du logiciel testé (A). Aujourd'hui, une intelligence artificielle forte capable de le faire n'a pas été créée.

      Figure 2 : représentation du logiciel de test
Figure 2 : représentation du logiciel de test

Pour commencer ce projet, nous avons décidé de le simplifier et de travailler uniquement sur un testeur de logiciel (E) capable d'explorer un autre logiciel automatiquement. Nous supposons que : l'évaluation du test est le nombre d'états que le logiciel a explorés (plus il explore d'états, meilleur il est).. Cela signifierait que le logiciel peut tester des séquences d'action non encore testées avec une faible manipulation humaine.

Pour "explorer" l'autre logiciel (A), le testeur (figure 3) devra d'abord déterminer l'action à réaliser. Cette première étape peut être considérée comme un "casier" car malgré les recherches, elle n'a pas encore été résolue. Sur le Dans la deuxième étape, le testeur a deux possibilités : générer des données (qui présentent un autre casier) et action de navigation (cliquer sur un bouton par exemple). S'il ne peut pas générer de données, il essaiera une action de navigation puis déterminera si l'état du logiciel testé a changé et raisonnera seul sur ce qu'il faut faire ensuite. Cela simplifie le problème, mais ne le rend pas plus facile.

Figure 3 : Principales étapes d'une exploration autosuffisante
Figure 3 : Principales étapes d'une exploration autosuffisante

L'état de l'art

Des générations de chercheurs ont travaillé sur ce problème à deux niveaux différents :
1st Au niveau industriel (il liste les outils et frameworks utilisables par tous) avec une approche directe. On en déduit que le code n'est pas le langage le plus facile à interpréter par tout le monde, qu'il apporte des bugs et un coût de maintenance important donc on semi-automatise les tests pour gagner du temps dessus. Cette solution est efficace sur des systèmes informatiques de petite ou moyenne taille.
Au deuxième niveau, l'approche est moins directe. Tout d'abord, ils déduisent des connaissances sur le logiciel testé et les introduisent dans une méthode choisie plus ou moins intelligente du type Web Mining ou Testeur de singes mais ces méthodes ne génèrent pas de données.
Pour créer une application intelligente de recherche, il est nécessaire de générer des données. Une approche scientifique est le test de fuzzer. Le site fuzzer va générer à partir d'une graine. Certains d'entre eux génèrent des données aléatoires (figure 4)d'autres apprendront par eux-mêmes. Par exemple, si les données générées atteignent un nouvel état, elles sont ajoutées au test de données, mais si l'état résultant est une erreur, le bogue est signalé.. Mais cette méthode ne tient pas compte de l'environnement de l'entreprise.
D'autres types de fuzzer basés sur l'intelligence artificielle, tels que Le fuzzer basé sur l'évolution améliorera certaines étapes avec l'apprentissage automatique et ajoutera des connaissances professionnelles au cours du processus..
Les solutions d'apprentissage automatique comme le Q-Learning, le réseau de neurones ou le GAN (Generative Adversarial Network) sont également de bonnes pistes à suivre.
L'étude de l'état de l'art scientifique montre des méthodes de génération automatisée. Même si ces méthodes sont adaptatives d'une application à une autre, elles ne prennent pas en compte de nombreuses informations sur la dimension métier. L'exploration ne génère donc pas de scénario métier cohérent. Une solution serait d'introduire des préconceptions métier pour générer un scénario et des données plus cohérents. Cependant, les préconceptions métier sont difficilement répertoriables sur les systèmes logiciels complexes.
Cette conclusion sur l'état de l'art existant, nous a amené à mener une étude sur un prototype de conception répondant à la problématique. La méthode utilisée a permis d'exposer autant que possible notre prototype aux casiers identifiés.

Figure 4 : Modèle "Fuzzer" basé sur le hasard
Figure 4 : Modèle "Fuzzer" basé sur le hasard

Détection et sélection d'éléments exploitables

Nous avons basé notre projet sur une application web existante de taille moyenne.
L'interaction automatique a été rendue possible grâce à un programme spécial (dans notre Selenium) capable d'agir sur l'IHM (interface homme-machine) - comme cliquer ou écrire du texte. (figure 5).

Figure 5 : Représentation du sélénium
Figure 5 : Représentation du sélénium

Il peut également lire le DOM (Document Object Model). (figure 6) et détecter les possibilités d'actions sur la page du site web.
Lorsqu'un bouton de la page est cliqué, il produit un événement qui modifie l'état du DOM (donc de la page web). Grâce au DOM, nous avons trouvé un moyen solide de déterminer si un élément du DOM provoquera un événement ou non. Une fois que tous les éléments actionnables ont été détectés dans le DOM, un élément est activé par Selenium. Son activation va éventuellement modifier le DOM, puis une nouvelle recherche d'élément actionnable commence. Le programme calcule une empreinte du DOM original, puis enregistre toutes les versions du DOM généré pour reconnaître l'état du DOM déjà rencontré et ne pas répéter une même action.. Si le DOM est composé de données professionnelles, l'exploration sera orientée scénario.

 6 : Exemple de DOM
6 : Exemple de DOM

Cette méthode est un bon moyen de détecter toutes les actions possibles, mais elle montre ses limites. Parfois, les actions listées ne peuvent pas être activées pour différentes raisons :

  • Même s'il est visible, un élément peut être partiellement ou totalement recouvert par un autre élément. (voir figure 7)
  • L'élément est en dehors de l'écran
  • L'élément est trop petit
Figure 7 : Exemple d'éléments cachés dans un formulaire
Figure 7 : Exemple d'éléments cachés dans un formulaire

Une partie de ces cas sont gérés automatiquement. Par exemple, dans le cas d'éléments superposés, le clic peut être intercepté par un élément parent. Il en résulte une erreur. Cependant, tous les cas ne sont pas gérés (comme les éléments extérieurs) et la gestion prend plus de temps.
Comme tous les éléments visibles ne sont pas actionnables, nous avons ajouté une analyse visuelle à l'analyse DOM. Chaque élément du DOM est colorisé pour définir une zone à laquelle attribuer le clic. La combinaison des deux méthodes permet de détecter tous les éléments actionnables et de déterminer s'ils sont actionnables dans la zone où se trouve l'analyseur.
Dans certains cas, l'analyse du DOM montre ses limites. Avec certains Framework (comme ReactJS) qui n'alimentent pas leur DOM comme d'habitude mais utilisent leurs propres modèles d'événements. La nouvelle tendance dynamique de l'application web rend l'analyse très difficile car le DOM est toujours en train de changer. Nous n'avons pas travaillé sur le cas du scroll dans notre étude, mais il apporte une forte complexité combinatoire, et demanderait une meilleure synergie entre le DOM et les analyses visuelles.

Génération de données

Nous avons travaillé sur la génération de données grâce à l'intelligence artificielle. Nous nous sommes interrogés sur la manière dont cela pouvait aider à générer suffisamment de données professionnelles. Nous avons croisé les données générées par le fuzzer avec celles issues du Q-Learning.
Dans cette architecture (figure 8) le fuzzer génère à partir de graines implémentées déjà sélectionnées par le Q-Learning. Le Q-Learning base son choix sur les données contextuelles de l'application. Par exemple, s'il détecte un champ "nom", le Q-Learning l'associera à une graine "textuelle". La fonction de récompense de l'algorithme (qui lui permet d'apprendre sur son expérience) est basée sur la validation ou le rejet du formulaire.

Figure 8 : Architecture globale du GTFA
Figure 8 : Architecture globale du GTFA

D'après notre étude de l'état de l'art, nous pouvons conclure qu'il est très difficile de créer une solution hyper automatisée capable d'être polyvalente à différents niveaux et dans différents environnements professionnels.. Pour ce faire, différents casiers scientifiques doivent être résolus : déterminer l'action à réaliser, générer des données, détecter un nouvel état.
Bien que l'analyse DOM combinée à une analyse visuelle soit intéressante, elle permet de déterminer avec précision les actions réalisables.même si des problèmes subsistent (le rouleau par exemple).
Il est très difficile de créer un logiciel générique sans tenir compte des besoins des utilisateurs, car les sites Web sont construits de manière différente.
Grâce à notre étude, nous avons appris la tendance des outils de test existants et les différentes approches d'analyse. En considérant les principaux verrous scientifiques identifiés, nous n'avons pas pu trouver une réponse satisfaisante, mais nous rappellerons notre étude de l'état de l'art et les connaissances cruciales pour notre travail futur.

Plus ...

Retour en haut