Partager via


Développer des tests à partir d’un modèle

Vous pouvez utiliser des exigences et des modèles architecturaux pour vous aider à organiser les tests de votre système et de ses composants. Cette pratique vous permet de vérifier que vous testez les exigences importantes pour les utilisateurs et d’autres parties prenantes, et vous aide à mettre à jour les tests rapidement lorsque les exigences changent. Si vous utilisez Microsoft Test Manager, vous pouvez également maintenir des liens entre les modèles et les tests.

Pour voir quelles versions de Visual Studio prennent en charge ces fonctionnalités, consultez La prise en charge de version pour les outils d’architecture et de modélisation.

Test du système et du sous-système

Le test système, également appelé test d’acceptation, signifie tester si les besoins des utilisateurs sont satisfaits. Ces tests sont préoccupés par le comportement visible externe du système au lieu de la conception interne.

Les tests système sont très utiles lors de l’extension ou de la refonte d’un système. Ils vous aident à éviter d’introduire des bogues lorsque vous modifiez le code.

Lorsque vous planifiez une modification ou une extension sur un système, il est utile de commencer par un ensemble de tests système qui s’exécutent sur le système existant. Vous pouvez ensuite étendre ou ajuster les tests pour tester les nouvelles exigences, apporter les modifications au code et réexécuter l’ensemble complet de tests.

Lorsque vous développez un nouveau système, vous pouvez commencer à créer des tests dès que le développement commence. En définissant des tests avant de développer chaque fonctionnalité, vous pouvez capturer les discussions sur les exigences d’une manière très spécifique.

Les tests de sous-système appliquent les mêmes principes aux principaux composants d’un système. Chaque composant est testé séparément des autres composants. Les tests du sous-système se concentrent sur le comportement visible sur les interfaces utilisateur ou l’API du composant.

Dérivation des tests système à partir d’un modèle de exigences

Vous pouvez créer et gérer une relation entre les tests système et un modèle de configuration requise. Pour établir cette relation, vous écrivez des tests qui correspondent aux éléments principaux du modèle de configuration requise. Visual Studio vous aide à maintenir cette relation en vous permettant de créer des liens entre les tests et les parties du modèle. Pour plus d’informations sur les modèles de configuration requise, consultez Configuration requise pour les utilisateurs de modèle.

Écrire des tests pour chaque cas d’usage

Si vous utilisez Microsoft Test Manager, vous pouvez créer un groupe de tests pour chaque cas d’usage que vous avez défini dans votre modèle de configuration requise. Par exemple, si vous avez un cas d’usage Commander un repas, qui inclut Créer une commande et Ajouter un article à la commande, vous pouvez créer des tests pour l'ensemble de ces cas d’usage ainsi que pour les plus détaillés.

Ces instructions peuvent être utiles :

  • Chaque cas d'usage doit comporter plusieurs tests, pour les scénarios principaux et les cas de résultats exceptionnels.

  • Lorsque vous décrivez un cas d’usage dans le modèle d’exigences, il est plus important de définir son postcondition, autrement dit, l’objectif atteint, que de décrire en détail les procédures que l’utilisateur suit afin d’atteindre l’objectif. Par exemple, la postcondition de commande d’un repas peut être qu’un restaurant prépare un repas pour un client et que le client a payé. La postcondition est le critère que vos tests doivent vérifier.

  • Basez des tests distincts sur les clauses distinctes de la postcondition. Par exemple, créez des tests distincts pour notifier le restaurant de la commande et pour prendre le paiement du client. Cette séparation présente les avantages suivants :

    • Les changements dans différents aspects des exigences se produisent fréquemment indépendamment. En séparant les tests en différents aspects de cette façon, vous facilitez la mise à jour des tests lorsque les exigences changent.

    • Si le plan de développement implémente un aspect du cas d’usage avant un autre, vous pouvez activer les tests séparément à mesure que le développement progresse.

  • Lorsque vous concevez les tests, séparez le choix des données de test du code ou du script qui détermine si la postcondition a été obtenue. Par exemple, un test d’une fonction arithmétique simple peut être : Entrée 4 ; vérifiez que la sortie est 2. Au lieu de cela, concevez le script comme suit : Choisir une entrée ; multipliez la sortie par elle-même et vérifiez que le résultat est l’entrée d’origine. Ce style vous permet de varier les entrées de test sans modifier le corps principal du test.

Liaison de tests à des cas d’usage

Si vous utilisez Le Gestionnaire de tests pour concevoir et exécuter vos tests, vous pouvez organiser vos tests en fonction des exigences, des cas d’usage ou des éléments de travail de l’article utilisateur. Vous pouvez lier ces éléments de travail aux cas d’usage dans votre modèle. Cela vous permet de suivre rapidement les modifications des exigences apportées aux tests et vous aide à suivre la progression de chaque cas d’usage.

  1. Dans Le Gestionnaire de tests, créez une exigence et basez-y une suite de tests.

    L’exigence que vous créez est un élément de travail dans Team Foundation Server. Il peut s’agir d’un élément de travail User Story, Requirement ou Use Case, selon le modèle de processus utilisé par votre projet avec Team Foundation. Pour plus d’informations, consultez À propos des outils Agile et de la gestion de projet Agile.

  2. Liez l’élément de travail requis à un ou plusieurs cas d’usage dans votre modèle.

    Dans un diagramme de cas d’usage, cliquez avec le bouton droit sur un cas d’usage, puis cliquez sur Lien vers l’élément de travail.

  3. Ajoutez à la suite de tests, les cas de test qui vérifient les cas d’usage.

    En règle générale, chaque article d’utilisateur ou élément de travail d’exigence est lié à plusieurs cas d’usage dans votre modèle, et chaque cas d’usage est lié à plusieurs récits utilisateur ou exigences. Cela est dû au fait que chaque article utilisateur ou exigence couvre un ensemble de tâches qui développent plusieurs cas d’usage. Par exemple, dans une itération précoce de votre projet, vous pouvez développer l’histoire utilisateur de base dans laquelle un client peut choisir des éléments à partir d’un catalogue et les livrer. Dans une itération ultérieure, l’histoire peut être que l’utilisateur paie lors de la commande, et le fournisseur reçoit l’argent après avoir envoyé les marchandises. Chaque histoire ajoute une clause à la postcondition du cas d’usage Commander des biens.

    Vous pouvez créer des liens distincts des exigences aux clauses de la postcondition en écrivant ces clauses dans des commentaires distincts sur le diagramme de cas d’usage. Vous pouvez lier chaque commentaire à un élément de travail d’exigence et lier le commentaire au cas d’usage sur le diagramme.

Tests de base sur les types de exigences

Les types, c’est-à-dire les classes, les interfaces et les énumérations, d’un modèle d’exigences décrivent les concepts et les relations en termes de la façon dont les utilisateurs pensent et communiquent sur leur entreprise. Il exclut les types concernés uniquement par la conception interne du système.

Concevez vos tests en termes de ces types d’exigences. Cette pratique vous permet de vous assurer que lorsque les modifications apportées aux exigences sont abordées, il est facile de lier les modifications aux modifications nécessaires dans les tests. Il permet de discuter des tests et de leurs résultats prévus directement avec les utilisateurs finaux et d’autres parties prenantes. Cela signifie que les besoins des utilisateurs peuvent être maintenus en dehors du processus de développement et éviter la conception accidentelle des tests autour des défauts possibles dans la conception.

Pour les tests manuels, cette pratique implique d’adhérer au vocabulaire du modèle d’exigences dans les scripts de test. Pour les tests automatisés, cette pratique implique l’utilisation des diagrammes de classes d’exigences comme base pour votre code de test, et la création de fonctions d’accesseur et de mise à jour pour lier le modèle requis au code.

Par exemple, un modèle de configuration requise peut inclure des types Menu, Élément de menu, Ordre et associations entre eux. Ce modèle représente les informations stockées et traitées par le système de commande de repas, mais ne représente pas les complexités de son implémentation. Dans le système de travail, il peut y avoir plusieurs réalisations différentes de chaque type, dans les bases de données, dans les interfaces utilisateur et sur les API. Dans un système distribué, il peut y avoir plusieurs variantes de chaque instance stockées dans différentes parties du système en même temps.

Pour tester un cas d’usage tel que Add Item to Order, une méthode de test peut inclure du code similaire à celui-ci :

Order order = ... ; // set up an order
// Store prior state:
int countBefore = order.MenuItems.Count;
// Perform use case:
MenuItem chosenItem = ...; // choose an item
AddItemToOrder (chosenItem, order);
// Verify part of postcondition:
int countAfter = order.MenuItems.Count;
Assert (countAfter == countBefore = 1);

Notez que cette méthode de test utilise les classes du modèle de configuration requise. Les associations et les attributs sont réalisés en tant que propriétés .NET.

Pour effectuer ce travail, les propriétés des classes doivent être définies en tant que fonctions ou accesseurs en lecture seule, qui accèdent au système pour récupérer des informations sur son état actuel. Les méthodes qui simulent des cas d’usage tels que AddItemToOrder doivent conduire le système via son API ou via une couche sous son interface utilisateur. Les constructeurs d’objets de test tels que Order et MenuItem doivent également conduire le système à créer des éléments correspondants à l’intérieur du système.

De nombreux accesseurs et mises à jour seront déjà disponibles via l’API normale de l’application. Toutefois, certaines fonctions supplémentaires peuvent être écrites afin d’activer les tests. Ces accesseurs et ces mises à jour supplémentaires sont parfois appelés « instrumentation de test ». Étant donné qu’ils dépendent de la conception interne du système, il incombe aux développeurs du système de les fournir, tandis que les testeurs écrivent le code des tests en termes de modèle d’exigences.

Lorsque vous écrivez des tests automatisés, vous pouvez utiliser des tests génériques pour encapsuler les accesseurs et les mises à jour.

Tests pour les règles d’entreprise

Certaines exigences ne sont pas directement liées à un cas d’usage. Par exemple, l’entreprise DinnerNow permet aux clients de choisir parmi de nombreux menus, mais exige que dans chaque commande, tous les éléments choisis proviennent d’un menu unique. Cette règle métier peut être exprimée en tant qu’invariant sur les associations entre commandes, menus et éléments dans le modèle de classe requis.

Une règle invariante de ce type régit non seulement tous les cas d’usage actuellement définis, mais également tous les autres cas d’usage qui seront définis ultérieurement. Par conséquent, il est utile de l’écrire séparément de n’importe quel cas d’usage et de le tester séparément des cas d’usage.

Dérivation de tests de sous-système à partir de modèles

Dans la conception générale d’un système volumineux, vous pouvez identifier des composants ou des sous-systèmes. Elles représentent des parties qui peuvent être conçues séparément, ou se trouvent sur différents ordinateurs, ou sont des modules réutilisables qui peuvent être combinés de plusieurs façons.

Vous pouvez appliquer à chaque composant principal les mêmes principes que vous utilisez pour le système complet. Dans un projet volumineux, chaque composant peut avoir son propre modèle de configuration requise. Dans des projets plus petits, un modèle architectural ou une conception de haut niveau peut être créé pour montrer les principaux composants et leurs interactions. Pour plus d’informations, consultez l’architecture de votre application.

Dans les deux cas, vous pouvez établir une relation entre les éléments de modèle et les tests du sous-système de la même manière que vous le feriez entre le modèle de configuration requise et les tests système.

Isoler les composants avec des interfaces fournies et requises

Il est utile d’identifier toutes les dépendances qu’un composant a sur d’autres parties de votre système ou des services externes, et de les représenter en tant qu’interfaces requises. Cet exercice conduit généralement à une nouvelle conception qui laisse le composant beaucoup plus découplé et facilement séparable du reste de votre conception.

Un avantage de ce découplage est que le composant peut être exécuté pour les tests en remplaçant par des objets fictifs les services qu’il utilise généralement. Il s’agit de composants configurés à des fins de test. Un composant fictif fournit l’interface dont votre composant a besoin, répondant aux requêtes avec des données simulées. Les composants fictifs font partie d’un harnais de test complet que vous pouvez connecter à toutes les interfaces du composant.

L’avantage des tests fictifs est que vous pouvez développer votre composant tandis que les autres composants dont les services qu’il utilisera sont toujours en cours de développement.

Maintenir les relations entre les tests et le modèle

Dans un projet classique qui effectue une itération toutes les semaines, une révision des exigences est tenue près du début de chaque itération. La réunion traite des fonctionnalités à remettre dans l’itération suivante. Un modèle d’exigences peut être utilisé pour discuter des concepts, des scénarios et des séquences d’actions qui seront développées. Les parties prenantes de l’entreprise définissent des priorités, les développeurs effectuent des estimations et les testeurs garantissent que le comportement attendu de chaque fonctionnalité est correctement capturé.

L’écriture de tests est le moyen le plus efficace de définir une exigence et est également un moyen efficace de s’assurer qu’une personne a une compréhension claire de ce qui est requis. Toutefois, alors que l’écriture de tests prend trop de temps à faire pendant un atelier de spécification, la création de modèles peut être beaucoup plus rapide.

D’un point de vue de test, un modèle de configuration requise peut être considéré comme un raccourci pour les tests. Par conséquent, il est important de maintenir la relation entre les tests et le modèle tout au long du projet.

Attachement de cas de test à des éléments de modèle

Si votre projet utilise Test Manager, vous pouvez lier des tests aux éléments de votre modèle. Cela vous permet de trouver rapidement les tests affectés par une modification des exigences et vous aide à suivre la mesure dans laquelle une exigence a été réalisée.

Vous pouvez lier des tests à tous les types d’éléments. Voici quelques exemples :

  • Lier un cas d’usage aux tests qui l’exercicent.

  • Écrivez les clauses d’une postcondition de cas d’usage, ou l’objectif, sur des commentaires liés au cas d’usage, puis liez des tests à chaque commentaire.

  • Écrivez des règles invariantes dans des commentaires sur des diagrammes de classes ou des diagrammes d’activité, puis liez-les aux tests.

  • Lier des tests à un diagramme d’activité ou à des activités individuelles.

  • Lier une suite de tests au composant ou au sous-système qu’il teste.

  1. Dans Le Gestionnaire de tests, créez une exigence et basez-y une suite de tests.

    L’exigence que vous créez est un élément de travail dans Team Foundation Server. Il peut s’agir d’un élément de travail User Story, Requirement ou Use Case, selon le modèle de processus utilisé par votre projet avec Team Foundation. Pour plus d’informations, consultez À propos des outils Agile et de la gestion de projet Agile.

  2. Liez l’élément de travail requis à un ou plusieurs éléments de votre modèle.

    Dans un diagramme de modélisation, cliquez avec le bouton droit sur un élément, un commentaire ou une relation, puis cliquez sur Lien vers l’élément de travail.

  3. Ajoutez à la suite de tests, les cas de test qui vérifient l’exigence exprimée dans l’élément de modèle.