Pourquoi le sélénium et le concombre ne devraient pas être utilisés ensemble

Dans cet article, j'expliquerai pourquoi je pense que c'est une mauvaise idée d'écrire des tests automatisés d'interface utilisateur avec Selenium et Cucumber.

Le titre de l'article mentionne Selenium et Cucumber, car ce sont respectivement les outils d'automatisation de navigateur et BDD les plus populaires, cependant, le contexte de cet article s'applique à tout outil d'automatisation d'interface utilisateur en combinaison avec n'importe quel outil BDD.

Avant d'approfondir, examinons quelques informations générales.




Qu'est-ce que le sélénium?

Sélénium est un outil de test d'automatisation de navigateur capable d'interagir avec les éléments HTML d'une application Web pour simuler l'activité de l'utilisateur.

Dans Selenium WebDriver, nous pouvons écrire des scripts dans un certain nombre de langages de programmation et peuvent être un excellent atout pour les tests de plusieurs OS et multi-navigateurs.




Qu'est-ce que le concombre?

Concombre a été créé pour piloter le processus BDD (Behavior Driven Development), de sorte que le client puisse décrire ses besoins sous la forme d'une série d'exemples appelés scénarios, dans des fichiers texte en utilisant le langage Gherkin au format Given When Then.

Dans le monde de Cucumber, ces fichiers sont appelés fichiers de fonctionnalités qui sont examinés par l'équipe Scrum pour obtenir une compréhension claire des exigences avant de commencer le développement proprement dit.

Une fois le développement en cours, les développeurs et / ou le contrôle qualité écriront des définitions d'étape qui sont essentiellement des extraits de code qui lient les scénarios des fichiers de fonctionnalités au code de test qui exécutent des actions contre l'application testée.



Sélénium et concombre

Le sélénium et le concombre sont tous deux d'excellents outils pour leurs propres besoins, mais lorsqu'ils sont utilisés ensemble, les choses ne se marient pas bien! Voyons pourquoi.


Les histoires sont généralement écrites du point de vue de l'utilisateur, par exemple:

Fonctionnalité: Fonctionnalité de connexion

En tant qu'utilisateur du site Web abc.com

Je souhaite que les clients puissent se connecter au site


Afin qu'ils puissent voir les informations de leur compte.

À leur tour, les scénarios dans les fichiers de fonctionnalités sont écrits de manière à décrire le comportement de la fonctionnalité lorsqu'un utilisateur interagit avec le application . Par example:

Scénario 1: Connexion valide

Étant donné que je suis sur la page de connexion abc.com


Lorsque j'entre des informations d'identification valides

Ensuite, je suis redirigé vers la page Mon compte

Et ainsi, vous pouvez ajouter plus de scénarios pour tester différentes combinaisons de données.

Parce que l'histoire et le fichier de fonctionnalités sont écrits d'un point de vue de haut niveau, et parce que nous voulons automatiser les scénarios, il semble naturel de commencer à écrire des définitions d'étape dans Cucumber qui appellent Selenium pour piloter l'application, effectuez les actions et vérifiez le résultat.


Mais, c'est là que le problème se produit; lorsque nous commençons à combiner Selenium avec Cucumber pour écrire des tests d'interface utilisateur automatisés.

En toute honnêteté, dans des cas simples comme le scénario de connexion ci-dessus, les choses vont bien ensemble et l'approche semble plausible, et en fait, la plupart des exemples que vous voyez sur Internet, démontrant l'utilisation de sélénium et de concombre, semblent se limiter au célèbre exemple de connexion.

Les lecteurs de tels blogs supposeraient qu'ils peuvent prendre le scénario de connexion simple et appliquer le même principe à un contexte plus large d'une application.

Ne soyez pas dupe cependant, car les choses peuvent devenir très aigres avec Selenium et Cucumber lorsqu'il est appliqué à une grande application Web réelle.

Prenons un exemple de page de résultats de recherche d’une application de commerce électronique classique qui vend des produits en ligne. Normalement, la page des résultats de la recherche regorge de fonctionnalités, telles que des filtres, des tris, une liste de produits, la possibilité de modifier la recherche, la possibilité de paginer ou de se charger automatiquement lors du défilement, etc., comme le montre la capture d'écran ci-dessous:

Je vais supposer que chaque fonctionnalité de la page de résultats de recherche a été ajoutée au site de manière incrémentielle à l'aide du développement agile.

En appliquant le même principe que notre exemple de connexion simple, au fur et à mesure que chaque fonctionnalité est développée, nous aurions un fichier de fonctionnalités respectif rempli de nombreux scénarios différents. Par example:

Dans l'itération 1 du développement, «Filtrer par prix» est développé, nous aurions donc un fichier de fonctionnalités pour celui-ci avec ses propres scénarios liés au filtre de prix.

Dans l'itération 2 du développement, «Filtrer par classement par étoiles» est développé, nous aurions donc un fichier de fonctionnalités pour celui-ci avec ses propres scénarios liés au filtre de classement par étoiles, et ainsi de suite pour chaque nouvelle fonctionnalité.

Il est important de noter que les scénarios de chaque fichier d'entités ne sont spécifiques qu'à leur fonction respective. En fait, c'est pourquoi ils sont appelés fichiers de fonctionnalités parce que l'accent est mis sur caractéristiques individuelles .

Comme mentionné précédemment, lorsque l'application est simple, nous pouvons survivre au défi d'automatiser les scénarios sur l'interface utilisateur avec Selenium et Cucumber. Cependant, au fur et à mesure que l'application se développe et que de nouvelles fonctionnalités sont ajoutées, la complexité apparaît car il pourrait y avoir des dépendances entre différentes fonctionnalités.

Par exemple, je pourrais d'abord filtrer mes résultats de recherche par prix, puis appliquer un autre filtre pour le nombre d'étoiles. Ah… nous avons maintenant un problème!

À quel fichier de fonctionnalités ce scénario doit-il maintenant être utilisé? Dans le fichier «Filtrer par classement par étoiles» ou «Filtrer par prix»? Et si j'ajoute maintenant un scénario pour appliquer un tri à mes résultats filtrés afin de trier par votes les plus élevés?

Si une partie prenante souhaite voir quelle est notre couverture de test, dans lequel des fichiers de fonctionnalités doit-elle se pencher? Obtiendra-t-il une image complète de la couverture du scénario en lisant un seul des fichiers de fonctionnalités ou devra-t-il lire tous les fichiers de fonctionnalités?

Au moment du développement, lorsque chaque fonctionnalité est développée une par une à chaque itération, les fichiers de fonctionnalités seraient concentrés sur la fonctionnalité elle-même, donc à un moment donné, lorsque nous avons plusieurs fonctionnalités, nous devons commencer à penser à les tester, pas seulement dans l'isolement mais aussi dans des scénarios créatifs où nous combinons différentes fonctionnalités.

Et en fait, c'est ce que feront les vrais utilisateurs de l'application. Ils entreront d'abord leurs critères de recherche, une fois sur la page de résultats de recherche, ils pagineront, filtreront, trieront, puis reviendront en arrière, et ainsi de suite, et ils pourront effectuer ces actions dans n'importe quel ordre. Il n’y aura pas d’ordre d’événements prescrit. C'est un véritable parcours utilisateur et un vrai test du système!

La majorité des bogues d'une application sont exposés lorsqu'une fonctionnalité elle-même est boguée ou lorsque deux fonctionnalités qui fonctionnent parfaitement bien isolément ne fonctionnent pas ensemble. C'est sur quoi repose le modèle de test par paires.

Alors, quel est le problème avec l'utilisation conjointe de sélénium et de concombre?

Dans la mesure du possible, nous ne devons pas utiliser l'interface graphique Web pour la vérification fonctionnelle. La fonctionnalité d'une fonctionnalité doit être testée au niveau de la couche API par des tests d'intégration.

L'interface utilisateur ne doit être réservée qu'à la vérification des flux de l'utilisateur dans l'application, ou aux tests de bout en bout et à s'assurer que les modules ou widgets attendus pertinents sont présents sur la page lorsque l'utilisateur navigue d'une page à l'autre.

Un parcours utilisateur typique impliquerait:

1 - Accédez à la page d'accueil du site abc.com

2 - Rechercher un produit depuis la page d'accueil

3 - Parcourez la liste des résultats de recherche

4 - Appliquer le filtre et / ou trier

5 - Lire les détails du produit

6 - Ajouter le produit au panier

7 - Continuer à payer…

Selenium est excellent pour automatiser ces scénarios et vérifier divers éléments sur chaque page et, comme je l'ai mentionné ci-dessus, c'est sur quoi nous devons nous concentrer lorsque nous testons au niveau de la couche d'interface utilisateur et testons les différentes transitions d'états.

Comme on peut le voir, chaque parcours utilisateur à travers l'application touche de nombreuses pages et interagit potentiellement avec plusieurs fonctionnalités sur chaque page, et nous vérifierions diverses choses à chaque étape du voyage, donc en utilisant un fichier de fonctionnalités documenter ces scénarios n'a absolument aucun sens, car nous ne testons pas une fonctionnalité, nous testons le système intégré.

Les choses vont vraiment en forme de poire lorsque nous essayons d'écrire les scénarios de bout en bout dans un format donné-quand-alors. Combien de Givens allons-nous avoir? Combien de Thens allons-nous avoir?

On pourrait soutenir que pour les tests de bout en bout, nous pourrions simplement utiliser Selenium seul sans le concombre et avoir des tests automatisés séparés pour chaque fonctionnalité utilisant Selenium et Cucumber. Encore une fois, je ne recommande pas cette approche car vous aurez peut-être des tests en double et nous savons à quel point les tests d'interface utilisateur sont lents et fragiles, nous devrions donc viser à en avoir moins, pas plus! De plus, vous devrez toujours faire face à des tests de dépendances de fonctionnalités.

Résumé

Cucumber est un excellent outil pour vérifier le comportement d'une fonctionnalité au niveau de la couche API avec des tests d'intégration où chaque fonctionnalité peut être testée de manière approfondie. Cet outil doit être utilisé pour les tests d'histoires.

Selenium est un excellent outil pour automatiser les scénarios utilisateur au niveau de l'interface utilisateur et vérifier le comportement du système dans son ensemble, englobant de nombreuses user stories.

Lorsque nous arrivons aux tests d'intégration système ou aux tests d'interface utilisateur, il est préférable d'utiliser Selenium sans le cadre Cucumber sous-jacent, car essayer d'écrire des fichiers de fonctionnalités Cucumber pour les voyages des utilisateurs, peut devenir très fastidieux et ne servirait pas l'objectif pour lequel l'outil est conçu.

Mon article est basé sur la déduction de faits!

  • S'il y a une valeur à utiliser le concombre, c'est au niveau de la fonctionnalité.
  • Il est préférable de vérifier la fonctionnalité d'une fonctionnalité en dehors de l'interface utilisateur, par exemple. Tests API.
  • Même lors des tests de couche API, le concombre échoue lamentablement.
  • Les tests d'interface utilisateur doivent couvrir des scénarios utilisateur / métier et non des fonctionnalités uniques.

Cucumber fonctionne à merveille avec une vue simpliste et naïve des tests et des scénarios, tels que la fonctionnalité de connexion préférée de tous.

Étant donné que je suis sur la page de connexion
Lorsque j'entre des informations d'identification valides
Alors je devrais voir mon compte

Mais tout testeur averti sait que même une simple fonctionnalité de connexion comporte de nombreuses vérifications. Essayez de convertir ces chèques en concombre.

Ceci est juste pour la connexion; essayez d'écrire un test de bout en bout sur le concombre!

Les tests d'interface utilisateur doivent couvrir les parcours des utilisateurs qui sont généralement de bout en bout et exercent plusieurs fonctionnalités d'une application.

Il y a beaucoup de choses qui se passent dans un seul parcours utilisateur à travers l'application.

Le concombre n'est certainement PAS le bon outil pour les tests de scénarios utilisateur / entreprise.