Dans cet article nous parlerons des tests end to end (E2E) pour des Front-end web. Ce sont des tests où nous testons l'application dans son intégralité à partir de son Front-end.
A la fin de cet article, vous aurez compris ce qu'est un test E2E, et en quoi cela est différent des autres types de test. Vous verrez également un exemple concret d'écriture de tests et aurez un rapide aperçu des outils existants pour vous permettre d'approfondir le sujet.
Les tests E2E peuvent être nommés différemment selon le contexte ou la communauté où l'on se place. Une review des différents noms utilisés peut nous aider à comprendre comment les écrire :
Les tests d'intégration : pour tester le Front-End sur un vrai navigateur, il faut un back-end qui ressemble le plus possible à celui de l'application en production. Cela nous permet aussi de valider l'intégration des composants du back-end. On appellera tests d'intégration tous les tests qui mettent en situation un ou plusieurs composants. Cela sans forcément passer par le Front-End ou utiliser un véritable navigateur.
Tests fonctionnels : ici on se met à la place d'un utilisateur, donc on se limite à des tests de scénarios qui ont un sens fonctionnel. La plupart du temps, ce n'est pas le moment de tester des edge cases. La plupart du temps pour tester des scénarios d'erreur en intégration ou unitaire, on se limitera à des scénarios happy path. Parfois, on appelle aussi "test fonctionnel", des tests au niveau de l'API exposée par le back-end. Dans ce cas, on n'a pas besoin d'exécuter le Front-End sur un navigateur, ces tests sont hors du scope de cet article.
Tests d'acceptation : on utilise cette nomenclature dans le monde BDD, où on commence par des tests d'acceptation qui peuvent être traduits et automatisés.
Tests E2E : on teste l'application d'un bout à l'autre en passant par son (ou ses) Front-end (s) et en simulant les actions des utilisateurs.
Les tests E2E validés
Nous pourrions nous dire qu'une fois les tests E2E validés par une batterie de tests assez complète, nous pouvons être confiant que l'application fonctionne. Dans la vraie vie, on se contentera de tester les quelques scénarios les plus importants, car il y a des trade-offs importants à considérer quand on les écrits :
Ils sont plus lents : en effet pour les tester il faut démarrer toute l'application. Un test E2E demande beaucoup plus de temps d'exécution qu'un test unitaire. Dans le cycle de développement, une phase de validation qui inclut des tests E2E, demandera souvent la recompilation de toute l'application. Cela rallonge donc le cycle de feedback entre l'écriture du code et son test.
Ils coûtent plus chers en infrastructure : comme il faut démarrer l'application dans des conditions les plus proches possibles des conditions de production, avec des bases de données et les services backend, il faut souvent une ou plusieurs machines virtuelles/réelles pour exécuter ces tests
Ils coûtent plus chers en développement : les tests E2E sont asynchrones par définition, ils sont donc beaucoup plus difficiles à écrire correctement. Quand ils ne sont pas bien écrits, ils peuvent avoir des résultats aléatoires à cause de race conditions ou d'une mauvaise gestion de l'état de l'application entre un test et un autre. L'investigation d'un test E2E coûte beaucoup plus cher que celle d'un test unitaire. Dans le premier cas, une erreur peut venir de n'importe quel composant de l'application. Alors que dans le second cas, cela viendra forcement des classes testées.
Dans un vrai projet, il convient donc de trouver un équilibre entre les différents types de tests. La figure suivante illustre les proportions qu'on trouvera le plus souvent. On donnera la priorité aux tests unitaires, ensuite on écrira des tests d'intégration et finalement, quelques tests E2E où on validera les scénarios les plus importants.
Exemple pratique d'automatisation de tests Front-End
Dans cette section on va illustrer des tests E2E par un petit exemple, où on testera la fonctionnalité "recherche" du blog INVIVOO. Il y a plein d'outils d'automatisation de tests Front-End. Il se basent tous sur le même principe d'écrire du code dont les primitives sont :
Des appels qui manipulent des pages web (des cliques, saisie des entrées etc)
Des asserts sur l'état de la page avant et/ou après les actions.
Ici, on va utiliser le framework cypress.io pour écrire un test simple.
Pour ceux qui ont l'habitude d'écrire des tests en JavaScript, les tests sont structurés d'une façon similaire à celle des tests jest. Dans un fichier, on aura des blocks describe où on regroupera tous les tests liés à une même entité. Et dans chaque block, on aura des blocks it qui seront chacun lié à un comportement/scénario implémenté par l'entité.
Dans l'exemple suivant, on teste la fonctionnalité Search du blog INVIVOO. On décrit la suite d'actions à exécuter sur le navigateur pour aller sur le blog, trouver le champ de recherche, déclencher une recherche avec des paramètres connus et on finit par un assert sur l'état final de la page web. On le mettra sur un fichier blog_search_spec.js.
Il faut utiliser la fonction cy.visit() pour aller sur le blog INVIVOO. Puis, on utilisera la fonction cy.get() pour chercher le champ de recherche à partir d'un sélecteur CSS et on tapera le texte this javascript avec la fonction type(). Finalement, on soumet le formulaire avec la fonction submit(), et on vérifie que l'article Comment utiliser l’opérateur this en Javascript est bien présent sur la page à la fin du test.
La figure suivante illustre l'exécution du test avec cypress.
Pour aller plus loin avec les tests front-end
Vous trouverez ci-dessous une liste non-exhaustive pour approfondir vos connaissances sur les test Front-End Web.
Articles
Voici quelques articles intéressants qui vous expliqueront un peu plus en détails les concepts autour des tests E2E et leur mise en pratique :
Tutorials
Des tutoriels sur TestCafé appliqués à des front ends comme React and Vue.js: A modern way to do E2E testing for Vue.js apps et E2E Testing React applications with TestCafe
Outils - Dans le monde web
PhantomJS- Full web stack. No browser required
CodeceptJS- Modern Era Acceptance Testing Framework for NodeJS
TestCafé- A node.js tool to automate end-to-end web testing
Nightwatch.js- Write End-to-End tests in Node.js quickly and effortlessly that run against a Selenium/WebDriver server
Protractor- end to end testing for Angular
CasperJS- Navigation scripting & testing for PhantomJS and SlimerJS
SlimerJS- A scriptable browser for Web developers
Capybara- Acceptance test framework for web applications
SeleniumHQ- Browser Automation
Headless Chrome- Essentially, running Chrome without chrome!
BrowserStack- Live, WebBased Browser Testing-
Sauce Labs- Continuous testing cloud
Outils - Dans le monde mobile
Appium- Automation for Apps
EarlGrey- iOS UI Automation Test Framework
Espresso Testing Framework- Use Espresso to write concise, beautiful, and reliable Android UI tests.
Calabash- Automated acceptance testing for mobile apps