Qu’est-ce qu’un test fonctionnel ?
Dans cette section, vous rejoignez l’équipe de Tailspin alors qu’elle définit des tests fonctionnels pour son pipeline. Les tests fonctionnels vérifient que chaque fonction du logiciel fonctionne comme prévu.
L’équipe commence par définir les éléments couverts par ce test fonctionnel. Elle explore certains types de tests fonctionnels. Elle décide ensuite du premier test à ajouter au pipeline.
Réunion hebdomadaire
L’équipe se retrouve pour la réunion hebdomadaire. Andy illustre le pipeline de mise en production. L’équipe observe les différentes phases d’un build réussi dans le pipeline. Pour finir, l’application web est promue vers la phase Staging.
Amita : Je suis très satisfaite du pipeline. Il me simplifie vraiment la vie. Tout d’abord, j’obtiens automatiquement une version déployée dans l’environnement de test. Cela signifie que je n’ai pas besoin de télécharger et d’installer manuellement les artefacts de build sur mes serveurs de test. Cela me fait gagner un temps considérable.
De plus, les tests unitaires que Mara et Andy ont écrits éliminent tous les bogues de régression avant que j’obtienne la version. Cela supprime une source importante de frustration. Je ne perds aucun temps à rechercher et à documenter les bogues de régression.
Cependant, je m’inquiète du fait que tous mes tests sont encore manuels. Le processus est lent et nous n’avons aucun résultat à montrer à l’équipe de gestion jusqu’à ce que je termine. C’est une situation difficile, car les tests sont importants. Ce sont eux qui garantissent que les utilisateurs bénéficient de l’expérience appropriée. Mais nous sommes contraints à des délais plus rapides.
Andy : Je suis sûr que nous pouvons t’aider. Quels sont les types de test qui prennent le plus de temps ?
Amita : Je pense que ce sont les tests de l’interface utilisateur. Je dois cliquer sur chaque étape pour m’assurer d’obtenir le bon résultat, et je dois le faire pour chaque navigateur que nous prenons en charge. Cela me prend beaucoup de temps. Alors que la complexité du site web augmente, les tests de l’interface utilisateur ne seront plus pratiques à long terme.
Mara : Les tests de l’interface utilisateur sont considérés comme des tests fonctionnels.
Tim : Par opposition à quoi ? Aux tests non fonctionnels ?
Mara : Tout à fait. Et les tests non fonctionnels te tiennent particulièrement à cœur.
Tim : Désolé, je ne te suis plus.
Qu’est-ce que les tests fonctionnels et non fonctionnels ?
Mara : Les tests fonctionnels vérifient que chaque fonction du logiciel fonctionne comme prévu. Ce n’est pas la façon dont le logiciel implémente chaque fonction qui est importante dans ces tests. Ce qui importe, c’est que le logiciel se comporte correctement. Vous donnez une entrée et vérifiez que la sortie correspond aux attentes. C’est ainsi qu’Amita effectue les tests de l’interface utilisateur. Par exemple, si elle sélectionne le joueur en tête du classement, elle s’attend à voir le profil de ce joueur.
Les tests non fonctionnels vérifient des caractéristiques telles que les performances et la fiabilité. Un exemple de test non fonctionnel consiste à vérifier combien de personnes peuvent se connecter simultanément à l’application. Les tests de charge sont un autre exemple de tests non fonctionnels. Ces aspects de performances et de fiabilité sont des éléments qui t’intéressent, Tim.
Tim : Oui, effectivement. Je dois y réfléchir un moment. Je souhaite éventuellement ajouter aussi de l’automatisation au pipeline, mais je ne suis pas sûr de ce que je veux faire. Quels sont les types de tests automatisés que je peux exécuter ?
Mara : Pour l’instant, nous allons nous concentrer sur les tests fonctionnels. C’est le genre de tests réalisés par Amita. Et apparemment, c’est un domaine que nous voulons améliorer.
Quels sont les types de tests fonctionnels que je peux exécuter ?
Il existe de nombreux types de tests fonctionnels. Ils varient en fonction de la fonctionnalité à tester, ainsi que du temps ou des efforts généralement requis pour leur exécution.
Les sections suivantes présentent certains tests fonctionnels couramment utilisés.
Tests de fumée
Les tests de fumée vérifient les fonctionnalités les plus basiques de votre application ou service. Ces tests sont souvent exécutés avant des tests plus complets et exhaustifs. Les tests de fumée doivent s’exécuter rapidement.
Imaginons par exemple que vous développez un site web. Votre test de fumée peut utiliser curl
pour vérifier que le site est accessible et que la récupération (fetch) de la page d’accueil produit un code d’état HTTP 200 (OK). Si la récupération (fetch) de la page d’accueil génère un autre code d’état, tel que 404 (Introuvable) ou 500 (Erreur interne du serveur), vous savez que le site web ne fonctionne pas. Vous savez également que cela ne sert à rien d’exécuter d’autres tests. Au lieu de cela, vous diagnostiquez l’erreur, la corrigez et redémarrez vos tests.
Effectuer des tests unitaires
Vous avez travaillé avec les tests unitaires dans le module Exécuter les tests de qualité dans votre pipeline de build à l’aide d’Azure Pipelines.
En résumé, les tests unitaires vérifient les composants essentiels de votre programme ou bibliothèque, comme une fonction ou une méthode individuelle. Vous spécifiez une ou plusieurs entrées ainsi que les résultats attendus. L’exécuteur de test effectue chaque test et vérifie si les résultats réels obtenus correspondent aux résultats attendus.
Par exemple, supposons que vous avez une fonction qui effectue une opération arithmétique incluant la division. Vous pouvez spécifier quelques valeurs que les utilisateurs sont susceptibles d’entrer. Vous spécifiez également des valeurs de cas limite telles que 0 et -1. Si vous vous attendez à ce qu’une certaine entrée génère une erreur ou une exception, vous pouvez vérifier que la fonction produit cette erreur.
Les tests de l’interface utilisateur que vous exécuterez plus tard dans ce module sont des tests unitaires.
Tests d’intégration
Les tests d’intégration vérifient que plusieurs composants logiciels fonctionnent ensemble pour constituer un système complet. Par exemple, un système d’e-commerce peut inclure un site web, une base de données de produits et un système de paiement. Vous pouvez écrire un test d’intégration qui ajoute des éléments au panier d’achat, puis achète les articles. Le test vérifie que l’application web peut se connecter à la base de données de produits, puis traiter la commande.
Vous pouvez combiner des tests unitaires et des tests d’intégration pour créer une stratégie de test en couches. Par exemple, vous pourriez exécuter des tests unitaires sur chacun de vos composants avant d’exécuter les tests d’intégration. Si tous les tests unitaires réussissent, vous pouvez passer aux tests d’intégration avec une plus grande confiance.
Effectuer des tests de régression
Une régression se produit quand le comportement existant change ou s’arrête après l’ajout ou la modification d’une fonctionnalité. Les tests de régression permettent de déterminer si des modifications du code, de la configuration ou autres affectent le comportement général du logiciel.
Les tests de régression sont importants, car une modification apportée à un composant peut affecter le comportement d’un autre composant. Imaginons par exemple que vous optimisez une base de données pour les performances d’écriture. Les performances de lecture de cette base de données, qui sont gérées par un autre composant, peuvent chuter de manière inattendue. La chute des performances de lecture est une régression.
Vous pouvez utiliser différentes stratégies pour tester la régression. En général, ces stratégies varient en fonction du nombre de tests que vous exécutez pour vérifier qu’une nouvelle fonctionnalité ou la résolution d’un bogue n’interrompt pas les fonctionnalités existantes. Toutefois, quand vous automatisez les tests, les tests de régression peuvent impliquer la simple exécution de l’ensemble de tests unitaires et de tests d’intégration à chaque modification du logiciel.
Tests d’intégrité
Les tests d’intégrité impliquent le test de chaque composant majeur d’un logiciel pour vérifier que le logiciel fonctionne et peut être soumis à des tests plus approfondis. Vous pouvez penser que les tests d’intégrité sont moins poussés que les tests de régression ou les tests unitaires, mais les tests d’intégrité sont plus étendus que les tests de détection de fumée.
Bien que les tests d’intégrité puissent être automatisés, ils sont souvent effectués manuellement en réponse à une modification de fonctionnalité ou à la résolution d’un bogue. Par exemple, un testeur de logiciel qui valide la résolution d’un bogue vérifiera probablement aussi que d’autres fonctionnalités marchent en entrant des valeurs typiques. Si le logiciel semble fonctionner comme prévu, il peut être soumis à une série de tests plus approfondis.
Test de l’interface utilisateur
Les tests de l’interface utilisateur vérifient le comportement de l’interface utilisateur d’une application. Les tests de l’interface utilisateur permettent de vérifier que la séquence (ou l’ordre) des interactions utilisateur aboutit au résultat attendu. Ces tests aident également à vérifier que les périphériques de saisie, comme le clavier ou la souris, affectent correctement l’interface utilisateur. Vous pouvez exécuter des tests de l’interface utilisateur pour vérifier le comportement d’une application Windows, macOS ou Linux native. Vous pouvez également utiliser des tests de l’interface utilisateur pour vérifier que l’interface utilisateur se comporte comme prévu sur les différents navigateurs web.
Un test unitaire ou un test d’intégration peut vérifier que l’interface utilisateur reçoit correctement les données. Mais les tests de l’interface utilisateur aident à vérifier que l’interface utilisateur s’affiche correctement et que le résultat fonctionne comme prévu pour l’utilisateur.
Par exemple, un test de l’interface utilisateur peut vérifier que l’animation correcte s’affiche en réponse à un clic sur un bouton. Un deuxième test peut vérifier que la même animation s’affiche correctement quand la fenêtre est redimensionnée.
Dans ce module, vous travaillez avec des tests de l’interface utilisateur qui sont codés manuellement. Toutefois, vous pouvez également utiliser un système de capture/relecture pour générer automatiquement vos tests de l’interface utilisateur.
Tests de la convivialité
Les tests de la convivialité sont une forme de tests manuels qui vérifient le comportement d’une application du point de vue de l’utilisateur. Les tests de la convivialité sont généralement effectués par l’équipe qui crée le logiciel.
Alors que les tests de l’interface utilisateur se concentrent sur une fonctionnalité afin de déterminer si elle se comporte de la manière attendue, les tests de la convivialité aident à vérifier que le logiciel est intuitif et répond aux besoins de l’utilisateur. En d’autres termes, les tests de la convivialité permettent de vérifier si le logiciel est « utilisable ».
Par exemple, imaginons que vous avez un site web qui inclut un lien vers le profil de l’utilisateur. Un test de l’interface utilisateur peut vérifier que le lien est présent et que le profil de l’utilisateur s’affiche bien quand on clique sur le lien. Toutefois, si les humains ne sont pas en mesure de localiser facilement ce lien, cela peut créer de la frustration quand ils essaient d’accéder à leur profil.
Tests d’acceptation utilisateur
Les tests d’acceptation utilisateur (UAT), tels que les tests de la convivialité, se concentrent sur le comportement d’une application du point de vue de l’utilisateur. Contrairement aux tests de convivialité, les tests UAT sont généralement effectués par des utilisateurs finaux réels.
Selon le logiciel, les utilisateurs finaux peuvent être invités à effectuer des tâches spécifiques. Ils peuvent aussi être autorisés à explorer le logiciel sans suivre d’instructions spécifiques. Pour les logiciels personnalisés, les tests UAT sont généralement réalisés directement avec le client. Pour les logiciels à usage plus général, les équipes peuvent exécuter des tests bêta. Dans les tests bêta, les utilisateurs de différentes régions géographiques ou les utilisateurs avec certains centres d’intérêt bénéficient d’un accès anticipé au logiciel.
Les commentaires des testeurs peuvent être directs ou indirects. Les commentaires directs peuvent prendre la forme de commentaires verbaux. Les commentaires indirects peuvent se présenter sous la forme de mesures concernant le langage corporel ou les mouvements oculaires des testeurs, ou bien de la durée nécessaire à l’exécution de certaines tâches.
Nous avons déjà abordé l’importance de l’écriture des tests. Mais pour insister sur ce point, voici une brève vidéo où Abel Wang, Cloud Advocate chez Microsoft, vous explique comment garantir la qualité de votre plan DevOps.
Demander à Abel
Que choisit l’équipe ?
Tim : Tous ces tests semblent importants. Par où devons-nous commencer ?
Andy : Nous disposons déjà de tests unitaires opérationnels. Nous ne sommes pas encore prêts à effectuer des tests d’acceptation utilisateur. D’après ce que j’ai compris, je pense que nous devrions nous concentrer sur les tests de l’interface utilisateur. Pour le moment, il s’agit de la partie la plus lente de notre processus. Amita, est-ce que tu es d’accord ?
Amita : Oui, je suis d’accord. Il nous reste un peu de temps dans cette réunion. Andy ou Mara, est-ce que vous voulez m’aider à planifier un test de l’interface utilisateur automatisé ?
Mara : Bien sûr. Mais commençons par prendre quelques décisions préliminaires. J’aimerais que nous débattions de l’outil qu’il convient d’utiliser et de la façon dont nous allons exécuter les tests.
Quels outils puis-je utiliser pour écrire des tests de l’interface utilisateur ?
Mara : Quelles sont nos options en matière d’écriture des tests de l’interface utilisateur ? Je sais qu’il en existe beaucoup. Certains outils sont open source. D’autres proposent un support commercial payant. Voici quelques options qui me viennent à l’esprit :
- Windows Application Driver (WinAppDriver) : WinAppDriver vous permet d’automatiser les tests de l’interface utilisateur sur les applications Windows. Ces applications peuvent être écrites dans la plateforme Windows universelle (UWP) ou Windows Forms (WinForms). Nous avons besoin d’une solution qui fonctionne dans un navigateur.
- Selenium : Selenium est une infrastructure de tests de logiciels portable et open source pour les applications web. Elle s’exécute sur la plupart des systèmes d’exploitation et prend en charge tous les navigateurs modernes. Vous pouvez écrire des tests Selenium dans plusieurs langages de programmation, notamment C#. En fait, vous pouvez utiliser des packages NuGet qui facilitent l’exécution de Selenium en tant que tests NUnit. Nous utilisons déjà NUnit pour nos tests unitaires.
- SpecFlow : SpecFlow est destiné aux projets .NET. Cet outil est inspiré par un outil appelé Cucumber. SpecFlow et Cucumber prennent tous les deux en charge le développement piloté par comportement (BDD). Le développement BDD utilise un analyseur de langage naturel appelé Gherkin pour aider à la fois les équipes techniques et les équipes non techniques à définir des règles et exigences métier. Vous pouvez combiner SpecFlow ou Cucumber avec Selenium pour générer des tests de l’interface utilisateur.
Andy regarde Amita.
Andy : Je sais que ces options sont nouvelles pour toi, es-tu d’accord pour que nous choisissions Selenium ? J’ai une certaine expérience de cet outil. Il prend en charge des langages que je connais déjà. Selenium offre également la prise en charge automatique de plusieurs navigateurs.
Amita : Bien sûr. C’est mieux si l’un d’entre nous a une certaine expérience.
Comment exécuter des tests fonctionnels dans le pipeline ?
Dans Azure Pipelines, vous exécutez des tests fonctionnels comme vous le feriez pour tout autre processus ou test. Posez-vous les questions suivantes :
- Dans quelle phase les tests seront-ils exécutés ?
- Sur quel système les tests seront-ils exécutés ? S’exécutent-t-ils sur l’agent ou sur l’infrastructure qui héberge l’application ?
Rejoignons l’équipe pour répondre à ces questions.
Mara : Ce que je trouve super, c’est que nous puissions maintenant effectuer des tests dans un environnement de production, où l’application est réellement exécutée. Les tests fonctionnels comme les tests de l’interface utilisateur sont judicieux dans ce contexte. Nous pouvons les exécuter dans la phase Test de notre pipeline.
Amita : Je suis d’accord. Nous pouvons conserver le même workflow si nous exécutons des tests de l’interface utilisateur automatisés dans la même phase que pour l’exécution de tests manuels. Les tests automatisés vont nous faire gagner du temps et me permettre de me concentrer sur la convivialité.
Tim : Amita teste le site web à partir de son ordinateur portable Windows car c’est ainsi que la plupart de nos utilisateurs consultent le site. Toutefois, nous générons le site sur Linux, puis nous déployons Azure App Service sur Linux. Comment gérer ce cas de figure ?
Mara : Très bonne question. Nous pouvons également choisir où nous effectuons les tests. Nous pouvons les exécuter :
- Sur l’agent : soit un agent Microsoft, soit un agent que nous hébergeons
- Sur l’infrastructure de test : localement ou dans le cloud
Notre phase Test existante inclut un travail. Ce travail déploie le site web sur App Service à partir d’un agent Linux. Nous pouvons ajouter un deuxième travail qui exécute les tests de l’interface utilisateur à partir d’un agent Windows. L’agent Windows hébergé par Microsoft est déjà configuré pour exécuter des tests Selenium.
Andy : Là encore, utilisons ce que nous connaissons. Nous allons utiliser un agent Windows hébergé par Microsoft. Plus tard, nous pourrons exécuter les mêmes tests à partir d’agents qui exécutent macOS et Linux si nous avons besoin d’une couverture de test supplémentaire.
Le plan
Mara : OK. Voici ce que nous allons faire :
- Exécuter des tests de l’interface utilisateur avec Selenium à partir d’un agent Windows hébergé par Microsoft
- Faire en sorte que les tests récupèrent le contenu web à partir de l’application qui s’exécute sur App Service, dans la phase Test
- Exécuter les tests sur tous les navigateurs que nous prenons en charge
Andy : Je vais travailler avec Amita sur ce projet. Amita, nous pouvons nous rencontrer demain matin. J’aimerais effectuer quelques recherches avant notre réunion.
Amita : Parfait ! À demain.
Créer un plan de test fonctionnel
Nous avons vu l’équipe décider de la façon dont elle souhaite implémenter les premiers tests fonctionnels. Si votre équipe commence tout juste à inclure des tests fonctionnels dans son pipeline (et même si vous le faites déjà), n’oubliez pas que vous avez toujours besoin d’un plan.
Souvent, quand les membres d’une équipe sont interrogés sur leur plan de test des performances, ils répondent généralement en énumérant la liste des outils qu’ils vont utiliser. Toutefois, un plan ne se réduit pas à une liste d’outils. Vous devez également trouver comment les environnements de test seront configurés. Vous devez déterminer les processus à utiliser et déterminer ce qui constitue une réussite ou un échec.
Assurez-vous que votre plan :
- Prend en compte les attentes de l’entreprise.
- Prend en compte les attentes des utilisateurs cibles.
- Définit les métriques que vous allez utiliser.
- Définit les indicateurs de performance clés que vous allez utiliser.
Les tests de performances doivent faire partie de votre planification dès le début. Si vous utilisez un plan conceptuel ou un tableau Kanban, vous pouvez envisager d’avoir une zone où vous pouvez planifier votre stratégie de test. Dans le cadre de la planification de l’itération, les lacunes de la stratégie de test doivent être mises en évidence. Il est également important de définir comment vous allez superviser les performances une fois l’application déployée et pas uniquement de mesurer les performances avant la publication de l’application.