A la découverte des tests d’interfaces graphiques avec Visual Studio 2010

Visual Studio 2010

Cet article a été écrit par Etienne MARGRAFF (http://blogs.codes-sources.com/etienne/), Ingénieur Consultant pour Winwise.

Sommaire

IntroductionIntroduction

Notre premier test (ou : « comment tester la calculatrice de Windows »)Notre premier test (ou : « comment tester la calculatrice de Windows »)

Qu’est ce qui est généré ?Qu’est ce qui est généré ?

Ajoutons de la validation à notre testAjoutons de la validation à notre test

ConclusionConclusion

 

NB : Cet article a été écrit avec la Community Technology Preview (CTP) d’Octobre 2008 de Visual Studio 2010

Introduction

Actuellement, la version 2008 de Visual Studio Team Test permet de couvrir un panel très important de type de tests. On peut réaliser des tests d’applications web, des tests unitaires, des tests de charge, des tests génériques, des tests de base de données, des tests manuels, et on peut même regrouper ces tests via des tests ordonnés. Tout le monde s’y retrouve dans cet ensemble d’outils plus aboutis les uns que les autres. Tout le monde ? En réalité, non… il manque un moyen simple d’automatiser le test d’une interface graphique, que ce soit des applications Winforms ou Windows Presentation Foundation, des applications web contenant du Javascript ou encore du Silverlight. Il y a bien les tests manuels qui permettent de définir un ensemble d’étape à réaliser pour tester l’application, mais cela demande toujours une intervention humaine. Et tout le monde sera d’accord sur le fait qu’aussi bien guidé qu’on puisse l’imaginer, le testeur commet des erreurs. Automatiser les tests d’interfaces graphiques est donc très important, d’autant plus que cela permet aux testeurs de gagner un temps précieux.

C’est pour ces raisons que Microsoft introduit dans sa version 2010 de Visual Studio les « Coded UI Tests » ou encore « Tests d’interfaces graphiques» en français pour plus de simplicité dans cet article.

Le principe des tests d’interfaces graphiques est très simple : un enregistreur intercepte toutes les actions que vous effectuez à la souris et au clavier et les transforme en code .NET. On se retrouve alors avec un ensemble de méthodes que l’on peut appeler et qui permettront de rejouer le(s) scénario(s) enregistré(s).

Notre premier test (ou : « comment tester la calculatrice de Windows »)

Le plus simple est de commencer par un exemple basique. Pour cela je vous propose de créer un premier test sur la calculatrice de Windows.

Le scénario que nous allons automatiser est le suivant :

  • Etape 1 : Lancement de l’application
  • Etape 2 : Effectuer une opération d’addition
  • Etape 3 : Fermer l’application

Ce scénario, malgré sa simplicité, vous permettra d’avoir une vision globale de l’enregistreur de Visual Studio.

Commençons par créer un projet de type « Test » (File > New > Project | Visual C# > Test > Test Project). Une fois le projet créé, ajoutons-y un nouveau test de type « Coded UI Test » (Project > Add New Test > Coded UI Test) que vous nommerez « CalculatriceUITest.cs ».

Visual Studio nous propose alors de choisir le type d’opération que nous voulons effectuer :

Code UI Test

Il y a 3 types d’enregistrement :

  • « Launch the recorder to generate code » : qui permet de lancer l’enregistreur et jouer manuellement le scénario que l’on souhaite automatiser
  • « User the UI Control Locator » : qui permet de lancer le localisateur de contrôle graphique dont nous parlerons un peu plus loin dans cet article et qui permet de sélectionner des contrôles pour générer du code permettant de valider leur(s) propriété(s) 
  • « User an existing automation strip » : qui permet de générer le code permettant de rejouer un test déjà enregistré

Pour notre test, choisissons la première option.

Visual Studio nous propose alors l’enregistreur de test d’interface graphique :

Test Recorder - CodedUITestMethod1

L’interface est très simple :

  • « Record » permet de lancer (ou relancer) l’enregistrement
  • « Pause » permet d’arrêter provisoirement l’enregistrement
  • « Reset » permet d’annuler toutes les actions enregistrées
  • « Delete » permet de supprimer la dernière action enregistrée
  • « Generate code » permet de générer le code permettant de rejouer les actions enregistrées
  • « Add Validation » permet de générer le code qui nous permettra de valider les propriétés des contrôles (que nous verrons un peu plus loin dans cet article)

Pour enregistrer notre scénario les étapes à réaliser sont les suivantes :

  • Lancer l’enregistrement
  • (Etape 1) Lancer l’application « Calculatrice Windows »
  • Cliquer sur « Generate Code » pour générer le code correspondant à l’étape 1 (donnez un nom de méthode explicite, par exemple : « DemarrageCalculatrice »)
  • Relancer l’enregistrement
  • (Etape 2) Effectuer une addition dans la calculatrice
  • Générer le code de cette étape et nommer la méthode
  • Relancer l’enregistrement
  • (Etape 3) Fermer la calculatrice
  • Générer le code de cette étape et nommer la méthode
  • Fermer l’enregistreur

Voici un exemple pour l’enregistrement de l’étape 2 :

Enter Method Name

Vous remarquerez que chaque action est listée de manière explicite. On peut alors facilement annuler une action si on se rend compte d’une erreur de manipulation.

Il ne nous reste plus qu’a rejouer ce test pour valider son bon fonctionnement. Pour cela, retournez dans Visual Studio et ouvrez l’explorateur de tests (Test > Windows > Test View). Vous devriez y trouver un test nommé « CodedUITestMethod1 » qui est le nom par défaut généré par Visual Studio.

Sélectionnez ce test et jouez-le (Clic Droit > Run Selection). C’est à ce moment que vous verrez la « magie » opérer : Visual Studio exécute la calculatrice, effectue l’addition et ferme l’application ! Rien de plus simple, n’est-ce pas ?

Test Results

C’est maintenant que vous vous posez certainement deux questions :

  • Comment cela fonctionne-t-il et qu’est-ce qui est généré ? (de manière à pouvoir personnaliser ces scénarios)
  • Comment est-ce que l’on peut ajouter une logique de validation ? (car un test tel qu’on vient de le réaliser n’est pas pertinent sans validation)

Il s’agit des sujets que je vous propose d’aborder dans les deux sections suivantes.

 

Qu’est ce qui est généré ?

L’automatisation de l’enregistrement du scénario est très importante et nous permet de créer rapidement un test d’interface graphique. Mais si l’on veut personnaliser le test et ajouter de la logique supplémentaire par exemple, il faut comprendre ce qui est généré par Visual Studio.

L’enregistrement d’un test crée 3 fichiers de code .NET :

  • Un fichier possédant le nom que nous avons donné à notre test (ici « CalculatriceUITest.cs »)
  • Un fichier « RecordedMethods.cs »
  • Un fichier « UserControls.cs »

Le premier fichier contient la logique de notre test. C’est lui qui contient la classe décorée de l’attribut [CodedUITest] (ici « CalculatriceUITest ») et qui définit la méthode « CodedUITestMethod1 » qui est créée par défaut et qui pilote le test :

[TestMethod]
public void CodedUITestMethod1()
{
    RecordedMethods.DemarrageCalculatrice();
    RecordedMethods.Addition();
    RecordedMethods.FermerCalculatrice();
}

Pour piloter le test, elle appelle séquentiellement un ensemble de méthodes statiques. Ces méthodes statiques ont été créées à chaque fois que nous avons demandé la génération du code correspondant à une étape de notre scénario de test. Elles sont définies dans le second fichier « RecordedMethods.cs ».

Ces méthodes peuvent être appelées autant de fois qu’on le désire. On pourrait par exemple imaginer effectuer plusieurs fois de suite l’addition, en modifiant le code de cette manière :

[TestMethod]
public void CodedUITestMethod1()
{
    RecordedMethods.DemarrageCalculatrice();

    //Effectue 5 additions
    for (int i = 0; i < 5; i++)
        RecordedMethods.Addition();

    RecordedMethods.FermerCalculatrice();
}

La classe « CalculatriceUITest » peut également contenir deux méthodes particulières, l’une permettant d’initialiser le test et l’autre de le terminer. On peut aisément trouver un rôle à ces méthodes en les utilisant pour lancer et fermer l’application, comme dans l’exemple suivant :

[TestMethod]
public void CodedUITestMethod1()
{
    for (int i = 0; i < 5; i++)
        RecordedMethods.Addition();
}

//Use TestInitialize to run code before running each test 
[TestInitialize()]
public void MyTestInitialize()
{
    RecordedMethods.DemarrageCalculatrice();
}

//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
    RecordedMethods.FermerCalculatrice();
}

Le 3ème fichier quant à lui contient un ensemble de classes héritant de « UITestControl ». Ces classes sont tout simplement des wrappers qui permettent au code généré dans la classe « RecordedMethods » de manipuler les composants graphiques de l’application que vous testez.

 Au final pour arriver à vos fins, vous n’aurez besoin dans la majeure partie des cas que de personnaliser le code contenu dans la classe principale : « CalculatriceUITest ».

Ajoutons de la validation à notre test

Maintenant que nous savons créer des tests d’interfaces graphiques et en personnaliser la logique, il reste le point le plus important à mon sens lorsque l’on réaliser un test : l’aspect de validation.

Pour cela il y a deux étapes à réaliser :

  • Sélectionner les contrôles que nous souhaitons valider
  • Indiquer quelles propriétés de ces contrôles nous voulons valider et comment nous voulons les valider

La première étape consiste à utiliser le localisateur des Coded UI Tests. Pour ajouter des contrôles à valider dans un test existant, il suffit de faire un clic droit dans le code de la méthode du test (ici : « CodedUITestMethod1() ») puis de lancer le localisateur (Edit CodedUITest > Add New UI Elements Using UI Control Locator…) :

Add New UI Elements Using UI Control Locator...

Visual Studio exécute alors un nouvel assistant :

Microsoft UI Control Locator

Son fonctionnement est des plus simples, il suffit de faire glisser/déposer la cible que l’on retrouve en haut à droite ( ) sur le contrôle de notre application ! Dans notre cas, nous allons vérifier que la valeur résultant de l’addition que nous effectuons dans notre test est bien la bonne. On fait donc glisser/déposer la cible sur le champ de texte de la calculatrice :

Calculator

L’outil crée alors une requête permettant récupérer l’identifiant du contrôle. Il ne nous reste plus qu’à ajouter ce contrôle à l’arborescence (« Add ») et à indiquer qu’on a terminé la sélection des contrôles (« Done »).

Nous avons maintenant une liste de contrôles que nous voulons valider (dans notre cas, la zone de texte uniquement). Il ne reste plus qu’à indiquer quelle(s) propriété(s) de ces contrôles nous souhaitons valider et à quoi, et comment, les comparer :

Microsoft UI Control Locator

Dans notre cas, nous sélectionnons « Value » qui contient la valeur de la zone de texte, le comparateur d’égalité « AreEqual », et la valeur de comparaison « 10 » (tout simplement le résultat de l’addition que nous simulons).

Dernière étape : générer le code (« Generate Code »). Visual Studio ajoute alors à notre méthode de test une assertion qui validera automatiquement la ou les propriétés du contrôle avec les valeurs de comparaison associées.

Le principe est le même que dans un test unitaire : si l’assertion (i.e. si la comparaison entre la valeur obtenue et la valeur attendue via la méthode choisie) n’est pas validée, le test échoue.

Pour notre exemple, le code généré est le suivant :

[TestMethod]
public void CodedUITestMethod1()
{
    RecordedMethods.Addition();

    // Value=10. 
    Assert.AreEqual("10", uiMap.CalculatorWindow.ItemWindow.ItemEdit.Value);
}

NB : Vous aurez certainement remarqué que l’outil de validation n’est pas automatiquement fermé  après la génération du code de comparaison. Cela est fait ainsi simplement pour vous permettre de continuer à ajouter d’autres règles dans votre test jusqu'à ce que vous ayez indiqué que vous avez terminé (« Finish »).

Lors de cette opération, en plus d’ajouter l’assertion dans votre méthode de test, Visual Studio crée deux fichiers :

  • Un fichier XML uiMap.uitest
  • Un fichier .NET uiMap.Designer.cs

Ces fichiers contiennent la logique permettant à Visual Studio de retrouver un contrôle dans l’application que vous testez. Le fichier d’extension .Designer.cs contient une classe « UIMap » qui est instanciée dans votre test et que vous pouvez manipuler via l’objet « uiMap » de la même manière que dans le code généré par Visual Studio dans l’assertion d’égalité de notre exemple.

Bien entendu, notre exemple est très simple et l’on pourrait imaginer des validations beaucoup plus poussées.

Conclusion

L’objectif de Visual Studio a toujours été de proposer à ses utilisateurs de faire toujours plus de choses, de plus en plus complexes, et ce, de plus en plus facilement. A mon avis, le but est atteint en termes de simplicité pour les tests d’interfaces graphiques. Mais attention : comme toujours dans la plateforme Team System, simplicité ne signifie pas limitations ! Le but de ce type de tests est de permettre aux testeurs de personnaliser à souhait leurs tests graphiques sans problèmes.

Dans cet article, je vous ai présenté le principe des Coded UI Tests avec un exemple pratique allant de l’enregistrement du scénario à la validation du résultat, en passant par la personnalisation de la logique du test.

Microsoft complète ses fonctionnalités de test avec les « Coded UI Tests » et propose aux équipes projets de s’engager dans une  voie vers un monde avec beaucoup plus de tests, moins de bugs, et plus d’utilisateurs satisfaits !