Partager via


Tutoriel : Tester une bibliothèque de classes .NET avec .NET à l’aide de Visual Studio

Ce tutoriel montre comment automatiser les tests unitaires en ajoutant un projet de test à une solution.

Prérequis

Créer un projet de test unitaire

Les tests unitaires effectuent des tests logiciels automatisés pendant le développement et la publication. MSTest est l’une des trois infrastructures de test parmi lesquelles vous pouvez choisir. Les autres sont xUnit et nUnit.

  1. Démarrez Visual Studio.

  2. Ouvrez la solution ClassLibraryProjects que vous avez créée dans Créer une bibliothèque de classes .NET à l’aide de Visual Studio.

  3. Ajoutez un nouveau projet de test unitaire nommé « StringLibraryTest » à la solution.

    1. Cliquez avec le bouton droit sur la solution dans l’Explorateur de solutions, puis sélectionnez Ajouter>Nouveau projet.

    2. Dans la page Ajouter un nouveau projet, entrez mstest dans la zone de recherche. Choisissez C# ou Visual Basic dans la liste de langages, puis choisissez Toutes les plateformes dans la liste des plateformes.

    3. Choisissez le modèle Projet de test MSTest, puis choisissez Suivant.

    4. Dans la page Configurer votre nouveau projet, entrez StringLibraryTest dans la zone Nom du projet. Ensuite, choisissez Suivant.

    5. Dans la page Informations supplémentaires, sélectionnez .NET 8 (Préversion) dans la zone Framework. Choisissez ensuite Créer.

  4. Visual Studio crée le projet et ouvre le fichier de classe dans la fenêtre de code avec le code suivant. Si le langage que vous souhaitez utiliser n’est pas affiché, modifiez le sélecteur de langage en haut de la page.

    namespace StringLibraryTest;
    
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    Le code source créé par le modèle de test unitaire effectue les opérations suivantes :

    Chaque méthode marquée avec [TestMethod] dans une classe de test marquée avec [TestClass] est exécutée automatiquement lorsque le test unitaire est exécuté.

Ajouter une référence au projet

Pour que le projet de test fonctionne avec la classe StringLibrary, ajoutez une référence dans le projet StringLibraryTest au projet StringLibrary.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud Dépendances du projet StringLibraryTest puis sélectionnez Ajouter une référence de projet dans le menu contextuel.

  2. Dans la boîte de dialogue Gestionnaire de références, développez le nœud Projets, cochez la case en regard de StringLibrary. L’ajout d’une référence à l’assembly StringLibrary permet au compilateur de rechercher des méthodes StringLibrary lors de la compilation du projet StringLibraryTest.

  3. Sélectionnez OK.

Ajouter et exécuter des méthodes de test unitaire

Lorsque Visual Studio exécute un test unitaire, il exécute chaque méthode marquée avec l’attribut TestMethodAttribute dans une classe marquée avec l’attribut TestClassAttribute. Une méthode de test se termine quand la première défaillance survient, ou quand tous les tests contenus dans la méthode ont réussi.

Les tests les plus courants appellent des membres de la classe Assert. De nombreuses méthodes d’assertion incluent au moins deux paramètres, à savoir le résultat attendu pour le test et résultat réel du test. Certaines des méthodes les plus fréquemment appelées de la classe Assert sont indiquées dans le tableau suivant :

Méthodes d’assertion Fonction
Assert.AreEqual Vérifie que deux valeurs ou objets sont égaux. L’assertion échoue si les valeurs ou les objets ne sont pas égaux.
Assert.AreSame Vérifie que deux variables d’objet référencent le même objet. L’assertion échoue si les variables font référence à des objets différents.
Assert.IsFalse Vérifie qu’une condition est false. L’assertion échoue si la condition est true.
Assert.IsNotNull Vérifie qu’un objet n’est pas null. L’assertion échouera si l’objet est null.

Vous pouvez également utiliser la méthode Assert.ThrowsException dans une méthode de test pour indiquer le type d’exception qu’il est censé lever. Le test échoue si l’exception spécifiée n’est pas levée.

Dans le test de la méthode StringLibrary.StartsWithUpper, vous voulez fournir une série de chaînes qui commencent par une majuscule. Vous attendez que la méthode retourne true dans de tels cas, et vous pouvez donc appeler la méthode Assert.IsTrue. De même, vous voulez fournir des chaînes qui commencent par autre chose qu’un caractère majuscule. Vous attendez que la méthode retourne false dans de tels cas, et vous pouvez donc appeler la méthode Assert.IsFalse.

Dans la mesure où votre méthode de bibliothèque gère les chaînes, vous voulez également vous assurer qu’elle gère correctement une chaîne vide (String.Empty), une chaîne valide sans caractères et dont Length a la valeur 0 et une chaîne null qui n’a pas été initialisée. Vous pouvez appeler StartsWithUpper directement en tant que méthode statique et passer un seul argument String. Vous pouvez également appeler StartsWithUpper en tant que méthode d’extension sur une variable string affectée à null.

Vous allez définir trois méthodes, chacune appelant une méthode Assert pour chaque élément d’un tableau de chaînes. Vous allez appeler une surcharge de méthode qui vous permet de spécifier un message d’erreur à afficher en cas d’échec du test. Le message identifie la chaîne qui a provoqué l’échec.

Pour créer les méthodes de test:

  1. Dans la fenêtre de code UnitTest1.cs ou UnitTest1.vb, remplacez le code par le code suivant :

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    Le test des caractères majuscules de la méthode TestStartsWithUpper inclut la lettre majuscule grecque alpha (U+0391) et la lettre majuscule cyrillique EM (U+041C). Le test des caractères minuscules dans la méthode TestDoesNotStartWithUpper inclut la lettre minuscule grecque alpha (U+03B1) et la lettre minuscule cyrillique Ghe (U+0433).

  2. Dans la barre de menus, sélectionnez Fichier>Enregistrer UnitTest1.cs sous ou Fichier>Enregistrer UnitTest1.vb sous. Dans la boîte de dialogue Enregistrer le fichier sous, cliquez sur la flèche à côté du bouton Enregistrer, puis choisissez Enregistrer avec l’encodage.

    Visual Studio Save File As dialog

  3. Dans la boîte de dialogue Confirmer l’enregistrement sous, sélectionnez le bouton Oui pour enregistrer le fichier.

  4. Dans la boîte de dialogue Options d’enregistrement avancées, sélectionnez Unicode (UTF-8 avec signature) - Page de codes 65001 dans la liste déroulante Encodage, puis sélectionnez OK.

    Visual Studio Advanced Save Options dialog

    Si vous ne parvenez pas à enregistrer votre code source dans un fichier encodé en UTF-8, Visual Studio peut l’enregistrer en tant que fichier ASCII. Dans ce cas, le runtime ne décode pas correctement les caractères UTF-8 en dehors de la plage ASCII, et les résultats des tests ne seront pas exacts.

  5. Dans la barre de menus, sélectionnez Test>Exécuter tous les tests. Si la fenêtre Explorateur de tests ne s’ouvre pas, ouvrez-la en choisissant Test>Explorateur de tests. Les trois tests sont listés dans la section Tests réussis et la section Résumé indique le résultat de la série de tests.

    Test Explorer window with passing tests

Gérer les échecs de test

Si vous effectuez un développement piloté par les tests (TDD), vous écrivez d’abord des tests et ils échouent la première fois que vous les exécutez. Ensuite, vous ajoutez du code à l’application, et le test réussit alors. Pour ce tutoriel, vous avez créé le test après avoir écrit le code de l’application qu’il valide, de sorte que vous n’avez pas vu le test échouer. Pour vérifier qu’un test échoue lorsque vous vous attendez à ce qu’il échoue, ajoutez une valeur non valide à l’entrée de test.

  1. Modifiez le tableau words dans la méthode TestDoesNotStartWithUpper en y incluant la chaîne « Erreur ». Vous n’avez pas besoin d’enregistrer le fichier, car Visual Studio enregistre automatiquement les fichiers ouverts quand une solution est générée pour exécuter des tests.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Exécutez le test en sélectionnant Test>Exécuter tous les tests dans la barre de menus. La fenêtre Explorateur de tests indique que deux tests ont réussi et qu’un test a échoué.

    Test Explorer window with failing tests

  3. Sélectionnez le test ayant échoué TestDoesNotStartWith.

    La fenêtre Explorateur de tests affiche le message généré par l’assertion : « Échec de Assert.IsFalse. « Erreur » : false ; réel : True » était attendu ». En raison de l’échec, aucune chaîne du tableau après « Erreur » n’a été testée.

    Test Explorer window showing the IsFalse assertion failure

  4. Supprimez la chaîne « Erreur » que vous avez ajoutée à l’étape 1. Réexécutez le test et les tests réussissent.

Tester la version Release de la bibliothèque

Maintenant que les tests ont tous réussi lors de l’exécution de la build Debug de la bibliothèque, exécutez les tests une fois supplémentaire sur la build Release de la bibliothèque. Un certain nombre de facteurs, notamment les optimisations du compilateur, peuvent parfois produire un comportement différent entre les versions Debug et Release.

Pour tester la version Release :

  1. Dans la barre d’outils de Visual Studio, modifiez la configuration de build de Debug à Release.

    Visual Studio toolbar with release build highlighted

  2. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet StringLibrary et sélectionnez Générer dans le menu contextuel pour recompiler la bibliothèque.

    StringLibrary context menu with build command

  3. Exécutez les tests unitaires en sélectionnant Test>Exécuter tous les t dans la barre de menus. Les tests réussissent.

Déboguer les tests

Si vous utilisez Visual Studio comme IDE, vous pouvez utiliser le même processus que celui présenté dans le Tutoriel : Déboguer une application console .NET à l’aide de Visual Studio pour déboguer du code à l’aide de votre projet de test unitaire. Au lieu de démarrer le projet d’application ShowCase, cliquez avec le bouton droit sur le projet StringLibraryTests, puis sélectionnez Déboguer les tests dans le menu contextuel.

Visual Studio démarre le projet de test avec le débogueur attaché. L’exécution s’arrête à tout point d’arrêt que vous avez ajouté au projet de test ou au code de bibliothèque sous-jacent.

Ressources supplémentaires

Étapes suivantes

Dans ce tutoriel, vous avez effectué le test unitaire d’une bibliothèque de classes. Vous pouvez rendre la bibliothèque accessible à d’autres utilisateurs en la publiant sur NuGet en tant que package. Pour en savoir plus, suivez un tutoriel NuGet :

Si vous publiez une bibliothèque en tant que package NuGet, d’autres utilisateurs peuvent l’installer et l’utiliser. Pour en savoir plus, suivez un tutoriel NuGet :

Une bibliothèque ne doit pas nécessairement être distribuée en tant que package. Elle peut être proposée avec une application console qui l’utilise. Pour savoir comment publier une application console, consultez le tutoriel précédent de cette série :

Ce tutoriel montre comment automatiser les tests unitaires en ajoutant un projet de test à une solution.

Prérequis

Créer un projet de test unitaire

Les tests unitaires effectuent des tests logiciels automatisés pendant le développement et la publication. MSTest est l’une des trois infrastructures de test parmi lesquelles vous pouvez choisir. Les autres sont xUnit et nUnit.

  1. Démarrez Visual Studio.

  2. Ouvrez la solution ClassLibraryProjects que vous avez créée dans Créer une bibliothèque de classes .NET à l’aide de Visual Studio.

  3. Ajoutez un nouveau projet de test unitaire nommé « StringLibraryTest » à la solution.

    1. Cliquez avec le bouton droit sur la solution dans l’Explorateur de solutions, puis sélectionnez Ajouter>Nouveau projet.

    2. Dans la page Ajouter un nouveau projet, entrez mstest dans la zone de recherche. Choisissez C# ou Visual Basic dans la liste de langages, puis choisissez Toutes les plateformes dans la liste des plateformes.

    3. Choisissez le modèle Projet de test MSTest, puis choisissez Suivant.

    4. Dans la page Configurer votre nouveau projet, entrez StringLibraryTest dans la zone Nom du projet. Ensuite, choisissez Suivant.

    5. Dans la page Informations supplémentaires, sélectionnez .NET 7 (prise en charge à terme standard) dans la zone Framework. Choisissez ensuite Créer.

  4. Visual Studio crée le projet et ouvre le fichier de classe dans la fenêtre de code avec le code suivant. Si le langage que vous souhaitez utiliser n’est pas affiché, modifiez le sélecteur de langage en haut de la page.

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    Le code source créé par le modèle de test unitaire effectue les opérations suivantes :

    Chaque méthode marquée avec [TestMethod] dans une classe de test marquée avec [TestClass] est exécutée automatiquement lorsque le test unitaire est exécuté.

Ajouter une référence au projet

Pour que le projet de test fonctionne avec la classe StringLibrary, ajoutez une référence dans le projet StringLibraryTest au projet StringLibrary.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud Dépendances du projet StringLibraryTest puis sélectionnez Ajouter une référence de projet dans le menu contextuel.

  2. Dans la boîte de dialogue Gestionnaire de références, développez le nœud Projets, cochez la case en regard de StringLibrary. L’ajout d’une référence à l’assembly StringLibrary permet au compilateur de rechercher des méthodes StringLibrary lors de la compilation du projet StringLibraryTest.

  3. Sélectionnez OK.

Ajouter et exécuter des méthodes de test unitaire

Lorsque Visual Studio exécute un test unitaire, il exécute chaque méthode marquée avec l’attribut TestMethodAttribute dans une classe marquée avec l’attribut TestClassAttribute. Une méthode de test se termine quand la première défaillance survient, ou quand tous les tests contenus dans la méthode ont réussi.

Les tests les plus courants appellent des membres de la classe Assert. De nombreuses méthodes d’assertion incluent au moins deux paramètres, à savoir le résultat attendu pour le test et résultat réel du test. Certaines des méthodes les plus fréquemment appelées de la classe Assert sont indiquées dans le tableau suivant :

Méthodes d’assertion Fonction
Assert.AreEqual Vérifie que deux valeurs ou objets sont égaux. L’assertion échoue si les valeurs ou les objets ne sont pas égaux.
Assert.AreSame Vérifie que deux variables d’objet référencent le même objet. L’assertion échoue si les variables font référence à des objets différents.
Assert.IsFalse Vérifie qu’une condition est false. L’assertion échoue si la condition est true.
Assert.IsNotNull Vérifie qu’un objet n’est pas null. L’assertion échouera si l’objet est null.

Vous pouvez également utiliser la méthode Assert.ThrowsException dans une méthode de test pour indiquer le type d’exception qu’il est censé lever. Le test échoue si l’exception spécifiée n’est pas levée.

Dans le test de la méthode StringLibrary.StartsWithUpper, vous voulez fournir une série de chaînes qui commencent par une majuscule. Vous attendez que la méthode retourne true dans de tels cas, et vous pouvez donc appeler la méthode Assert.IsTrue. De même, vous voulez fournir des chaînes qui commencent par autre chose qu’un caractère majuscule. Vous attendez que la méthode retourne false dans de tels cas, et vous pouvez donc appeler la méthode Assert.IsFalse.

Dans la mesure où votre méthode de bibliothèque gère les chaînes, vous voulez également vous assurer qu’elle gère correctement une chaîne vide (String.Empty), une chaîne valide sans caractères et dont Length a la valeur 0 et une chaîne null qui n’a pas été initialisée. Vous pouvez appeler StartsWithUpper directement en tant que méthode statique et passer un seul argument String. Vous pouvez également appeler StartsWithUpper en tant que méthode d’extension sur une variable string affectée à null.

Vous allez définir trois méthodes, chacune appelant une méthode Assert pour chaque élément d’un tableau de chaînes. Vous allez appeler une surcharge de méthode qui vous permet de spécifier un message d’erreur à afficher en cas d’échec du test. Le message identifie la chaîne qui a provoqué l’échec.

Pour créer les méthodes de test:

  1. Dans la fenêtre de code UnitTest1.cs ou UnitTest1.vb, remplacez le code par le code suivant :

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    Le test des caractères majuscules de la méthode TestStartsWithUpper inclut la lettre majuscule grecque alpha (U+0391) et la lettre majuscule cyrillique EM (U+041C). Le test des caractères minuscules dans la méthode TestDoesNotStartWithUpper inclut la lettre minuscule grecque alpha (U+03B1) et la lettre minuscule cyrillique Ghe (U+0433).

  2. Dans la barre de menus, sélectionnez Fichier>Enregistrer UnitTest1.cs sous ou Fichier>Enregistrer UnitTest1.vb sous. Dans la boîte de dialogue Enregistrer le fichier sous, cliquez sur la flèche à côté du bouton Enregistrer, puis choisissez Enregistrer avec l’encodage.

    Visual Studio Save File As dialog

  3. Dans la boîte de dialogue Confirmer l’enregistrement sous, sélectionnez le bouton Oui pour enregistrer le fichier.

  4. Dans la boîte de dialogue Options d’enregistrement avancées, sélectionnez Unicode (UTF-8 avec signature) - Page de codes 65001 dans la liste déroulante Encodage, puis sélectionnez OK.

    Visual Studio Advanced Save Options dialog

    Si vous ne parvenez pas à enregistrer votre code source dans un fichier encodé en UTF-8, Visual Studio peut l’enregistrer en tant que fichier ASCII. Dans ce cas, le runtime ne décode pas correctement les caractères UTF-8 en dehors de la plage ASCII, et les résultats des tests ne seront pas exacts.

  5. Dans la barre de menus, sélectionnez Test>Exécuter tous les tests. Si la fenêtre Explorateur de tests ne s’ouvre pas, ouvrez-la en choisissant Test>Explorateur de tests. Les trois tests sont listés dans la section Tests réussis et la section Résumé indique le résultat de la série de tests.

    Test Explorer window with passing tests

Gérer les échecs de test

Si vous effectuez un développement piloté par les tests (TDD), vous écrivez d’abord des tests et ils échouent la première fois que vous les exécutez. Ensuite, vous ajoutez du code à l’application, et le test réussit alors. Pour ce tutoriel, vous avez créé le test après avoir écrit le code de l’application qu’il valide, de sorte que vous n’avez pas vu le test échouer. Pour vérifier qu’un test échoue lorsque vous vous attendez à ce qu’il échoue, ajoutez une valeur non valide à l’entrée de test.

  1. Modifiez le tableau words dans la méthode TestDoesNotStartWithUpper en y incluant la chaîne « Erreur ». Vous n’avez pas besoin d’enregistrer le fichier, car Visual Studio enregistre automatiquement les fichiers ouverts quand une solution est générée pour exécuter des tests.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Exécutez le test en sélectionnant Test>Exécuter tous les tests dans la barre de menus. La fenêtre Explorateur de tests indique que deux tests ont réussi et qu’un test a échoué.

    Test Explorer window with failing tests

  3. Sélectionnez le test ayant échoué TestDoesNotStartWith.

    La fenêtre Explorateur de tests affiche le message généré par l’assertion : « Échec de Assert.IsFalse. « Erreur » : false ; réel : True » était attendu ». En raison de l’échec, aucune chaîne du tableau après « Erreur » n’a été testée.

    Test Explorer window showing the IsFalse assertion failure

  4. Supprimez la chaîne « Erreur » que vous avez ajoutée à l’étape 1. Réexécutez le test et les tests réussissent.

Tester la version Release de la bibliothèque

Maintenant que les tests ont tous réussi lors de l’exécution de la build Debug de la bibliothèque, exécutez les tests une fois supplémentaire sur la build Release de la bibliothèque. Un certain nombre de facteurs, notamment les optimisations du compilateur, peuvent parfois produire un comportement différent entre les versions Debug et Release.

Pour tester la version Release :

  1. Dans la barre d’outils de Visual Studio, modifiez la configuration de build de Debug à Release.

    Visual Studio toolbar with release build highlighted

  2. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet StringLibrary et sélectionnez Générer dans le menu contextuel pour recompiler la bibliothèque.

    StringLibrary context menu with build command

  3. Exécutez les tests unitaires en sélectionnant Test>Exécuter tous les t dans la barre de menus. Les tests réussissent.

Déboguer les tests

Si vous utilisez Visual Studio comme IDE, vous pouvez utiliser le même processus que celui présenté dans le Tutoriel : Déboguer une application console .NET à l’aide de Visual Studio pour déboguer du code à l’aide de votre projet de test unitaire. Au lieu de démarrer le projet d’application ShowCase, cliquez avec le bouton droit sur le projet StringLibraryTests, puis sélectionnez Déboguer les tests dans le menu contextuel.

Visual Studio démarre le projet de test avec le débogueur attaché. L’exécution s’arrête à tout point d’arrêt que vous avez ajouté au projet de test ou au code de bibliothèque sous-jacent.

Ressources supplémentaires

Étapes suivantes

Dans ce tutoriel, vous avez effectué le test unitaire d’une bibliothèque de classes. Vous pouvez rendre la bibliothèque accessible à d’autres utilisateurs en la publiant sur NuGet en tant que package. Pour en savoir plus, suivez un tutoriel NuGet :

Si vous publiez une bibliothèque en tant que package NuGet, d’autres utilisateurs peuvent l’installer et l’utiliser. Pour en savoir plus, suivez un tutoriel NuGet :

Une bibliothèque ne doit pas nécessairement être distribuée en tant que package. Elle peut être proposée avec une application console qui l’utilise. Pour savoir comment publier une application console, consultez le tutoriel précédent de cette série :

Ce tutoriel montre comment automatiser les tests unitaires en ajoutant un projet de test à une solution.

Prérequis

Créer un projet de test unitaire

Les tests unitaires effectuent des tests logiciels automatisés pendant le développement et la publication. MSTest est l’une des trois infrastructures de test parmi lesquelles vous pouvez choisir. Les autres sont xUnit et nUnit.

  1. Démarrez Visual Studio.

  2. Ouvrez la solution ClassLibraryProjects que vous avez créée dans Créer une bibliothèque de classes .NET à l’aide de Visual Studio.

  3. Ajoutez un nouveau projet de test unitaire nommé « StringLibraryTest » à la solution.

    1. Cliquez avec le bouton droit sur la solution dans l’Explorateur de solutions, puis sélectionnez Ajouter>Nouveau projet.

    2. Dans la page Ajouter un nouveau projet, entrez mstest dans la zone de recherche. Choisissez C# ou Visual Basic dans la liste de langages, puis choisissez Toutes les plateformes dans la liste des plateformes.

    3. Choisissez le modèle Projet de test MSTest, puis choisissez Suivant.

    4. Dans la page Configurer votre nouveau projet, entrez StringLibraryTest dans la zone Nom du projet. Ensuite, choisissez Suivant.

    5. Dans la page Informations supplémentaires, sélectionnez .NET 6 (prise en charge à long terme) dans la zone Framework. Choisissez ensuite Créer.

  4. Visual Studio crée le projet et ouvre le fichier de classe dans la fenêtre de code avec le code suivant. Si le langage que vous souhaitez utiliser n’est pas affiché, modifiez le sélecteur de langage en haut de la page.

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    Le code source créé par le modèle de test unitaire effectue les opérations suivantes :

    Chaque méthode marquée avec [TestMethod] dans une classe de test marquée avec [TestClass] est exécutée automatiquement lorsque le test unitaire est exécuté.

Ajouter une référence au projet

Pour que le projet de test fonctionne avec la classe StringLibrary, ajoutez une référence dans le projet StringLibraryTest au projet StringLibrary.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud Dépendances du projet StringLibraryTest puis sélectionnez Ajouter une référence de projet dans le menu contextuel.

  2. Dans la boîte de dialogue Gestionnaire de références, développez le nœud Projets, cochez la case en regard de StringLibrary. L’ajout d’une référence à l’assembly StringLibrary permet au compilateur de rechercher des méthodes StringLibrary lors de la compilation du projet StringLibraryTest.

  3. Sélectionnez OK.

Ajouter et exécuter des méthodes de test unitaire

Lorsque Visual Studio exécute un test unitaire, il exécute chaque méthode marquée avec l’attribut TestMethodAttribute dans une classe marquée avec l’attribut TestClassAttribute. Une méthode de test se termine quand la première défaillance survient, ou quand tous les tests contenus dans la méthode ont réussi.

Les tests les plus courants appellent des membres de la classe Assert. De nombreuses méthodes d’assertion incluent au moins deux paramètres, à savoir le résultat attendu pour le test et résultat réel du test. Certaines des méthodes les plus fréquemment appelées de la classe Assert sont indiquées dans le tableau suivant :

Méthodes d’assertion Fonction
Assert.AreEqual Vérifie que deux valeurs ou objets sont égaux. L’assertion échoue si les valeurs ou les objets ne sont pas égaux.
Assert.AreSame Vérifie que deux variables d’objet référencent le même objet. L’assertion échoue si les variables font référence à des objets différents.
Assert.IsFalse Vérifie qu’une condition est false. L’assertion échoue si la condition est true.
Assert.IsNotNull Vérifie qu’un objet n’est pas null. L’assertion échouera si l’objet est null.

Vous pouvez également utiliser la méthode Assert.ThrowsException dans une méthode de test pour indiquer le type d’exception qu’il est censé lever. Le test échoue si l’exception spécifiée n’est pas levée.

Dans le test de la méthode StringLibrary.StartsWithUpper, vous voulez fournir une série de chaînes qui commencent par une majuscule. Vous attendez que la méthode retourne true dans de tels cas, et vous pouvez donc appeler la méthode Assert.IsTrue. De même, vous voulez fournir des chaînes qui commencent par autre chose qu’un caractère majuscule. Vous attendez que la méthode retourne false dans de tels cas, et vous pouvez donc appeler la méthode Assert.IsFalse.

Dans la mesure où votre méthode de bibliothèque gère les chaînes, vous voulez également vous assurer qu’elle gère correctement une chaîne vide (String.Empty), une chaîne valide sans caractères et dont Length a la valeur 0 et une chaîne null qui n’a pas été initialisée. Vous pouvez appeler StartsWithUpper directement en tant que méthode statique et passer un seul argument String. Vous pouvez également appeler StartsWithUpper en tant que méthode d’extension sur une variable string affectée à null.

Vous allez définir trois méthodes, chacune appelant une méthode Assert pour chaque élément d’un tableau de chaînes. Vous allez appeler une surcharge de méthode qui vous permet de spécifier un message d’erreur à afficher en cas d’échec du test. Le message identifie la chaîne qui a provoqué l’échec.

Pour créer les méthodes de test:

  1. Dans la fenêtre de code UnitTest1.cs ou UnitTest1.vb, remplacez le code par le code suivant :

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    Le test des caractères majuscules de la méthode TestStartsWithUpper inclut la lettre majuscule grecque alpha (U+0391) et la lettre majuscule cyrillique EM (U+041C). Le test des caractères minuscules dans la méthode TestDoesNotStartWithUpper inclut la lettre minuscule grecque alpha (U+03B1) et la lettre minuscule cyrillique Ghe (U+0433).

  2. Dans la barre de menus, sélectionnez Fichier>Enregistrer UnitTest1.cs sous ou Fichier>Enregistrer UnitTest1.vb sous. Dans la boîte de dialogue Enregistrer le fichier sous, cliquez sur la flèche à côté du bouton Enregistrer, puis choisissez Enregistrer avec l’encodage.

    Visual Studio Save File As dialog

  3. Dans la boîte de dialogue Confirmer l’enregistrement sous, sélectionnez le bouton Oui pour enregistrer le fichier.

  4. Dans la boîte de dialogue Options d’enregistrement avancées, sélectionnez Unicode (UTF-8 avec signature) - Page de codes 65001 dans la liste déroulante Encodage, puis sélectionnez OK.

    Visual Studio Advanced Save Options dialog

    Si vous ne parvenez pas à enregistrer votre code source dans un fichier encodé en UTF-8, Visual Studio peut l’enregistrer en tant que fichier ASCII. Dans ce cas, le runtime ne décode pas correctement les caractères UTF-8 en dehors de la plage ASCII, et les résultats des tests ne seront pas exacts.

  5. Dans la barre de menus, sélectionnez Test>Exécuter tous les tests. Si la fenêtre Explorateur de tests ne s’ouvre pas, ouvrez-la en choisissant Test>Explorateur de tests. Les trois tests sont listés dans la section Tests réussis et la section Résumé indique le résultat de la série de tests.

    Test Explorer window with passing tests

Gérer les échecs de test

Si vous effectuez un développement piloté par les tests (TDD), vous écrivez d’abord des tests et ils échouent la première fois que vous les exécutez. Ensuite, vous ajoutez du code à l’application, et le test réussit alors. Pour ce tutoriel, vous avez créé le test après avoir écrit le code de l’application qu’il valide, de sorte que vous n’avez pas vu le test échouer. Pour vérifier qu’un test échoue lorsque vous vous attendez à ce qu’il échoue, ajoutez une valeur non valide à l’entrée de test.

  1. Modifiez le tableau words dans la méthode TestDoesNotStartWithUpper en y incluant la chaîne « Erreur ». Vous n’avez pas besoin d’enregistrer le fichier, car Visual Studio enregistre automatiquement les fichiers ouverts quand une solution est générée pour exécuter des tests.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Exécutez le test en sélectionnant Test>Exécuter tous les tests dans la barre de menus. La fenêtre Explorateur de tests indique que deux tests ont réussi et qu’un test a échoué.

    Test Explorer window with failing tests

  3. Sélectionnez le test ayant échoué TestDoesNotStartWith.

    La fenêtre Explorateur de tests affiche le message généré par l’assertion : « Échec de Assert.IsFalse. « Erreur » : false ; réel : True » était attendu ». En raison de l’échec, aucune chaîne du tableau après « Erreur » n’a été testée.

    Test Explorer window showing the IsFalse assertion failure

  4. Supprimez la chaîne « Erreur » que vous avez ajoutée à l’étape 1. Réexécutez le test et les tests réussissent.

Tester la version Release de la bibliothèque

Maintenant que les tests ont tous réussi lors de l’exécution de la build Debug de la bibliothèque, exécutez les tests une fois supplémentaire sur la build Release de la bibliothèque. Un certain nombre de facteurs, notamment les optimisations du compilateur, peuvent parfois produire un comportement différent entre les versions Debug et Release.

Pour tester la version Release :

  1. Dans la barre d’outils de Visual Studio, modifiez la configuration de build de Debug à Release.

    Visual Studio toolbar with release build highlighted

  2. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet StringLibrary et sélectionnez Générer dans le menu contextuel pour recompiler la bibliothèque.

    StringLibrary context menu with build command

  3. Exécutez les tests unitaires en sélectionnant Test>Exécuter tous les t dans la barre de menus. Les tests réussissent.

Déboguer les tests

Si vous utilisez Visual Studio comme IDE, vous pouvez utiliser le même processus que celui présenté dans le Tutoriel : Déboguer une application console .NET à l’aide de Visual Studio pour déboguer du code à l’aide de votre projet de test unitaire. Au lieu de démarrer le projet d’application ShowCase, cliquez avec le bouton droit sur le projet StringLibraryTests, puis sélectionnez Déboguer les tests dans le menu contextuel.

Visual Studio démarre le projet de test avec le débogueur attaché. L’exécution s’arrête à tout point d’arrêt que vous avez ajouté au projet de test ou au code de bibliothèque sous-jacent.

Ressources supplémentaires

Étapes suivantes

Dans ce tutoriel, vous avez effectué le test unitaire d’une bibliothèque de classes. Vous pouvez rendre la bibliothèque accessible à d’autres utilisateurs en la publiant sur NuGet en tant que package. Pour en savoir plus, suivez un tutoriel NuGet :

Si vous publiez une bibliothèque en tant que package NuGet, d’autres utilisateurs peuvent l’installer et l’utiliser. Pour en savoir plus, suivez un tutoriel NuGet :

Une bibliothèque ne doit pas nécessairement être distribuée en tant que package. Elle peut être proposée avec une application console qui l’utilise. Pour savoir comment publier une application console, consultez le tutoriel précédent de cette série :