Concepts de base des tests unitaires

Vérifiez que votre code fonctionne comme prévu en créant et en exécutant des tests unitaires. Un test unitaire consiste à décomposer les fonctionnalités de votre programme en comportements testables discrets que vous pouvez tester en tant qu’unités individuelles. L’explorateur de tests de Visual Studio offre un moyen souple et efficace d’exécuter vos tests unitaires et d’afficher leurs résultats dans Visual Studio. Visual Studio installe les infrastructures de tests unitaires Microsoft pour le code managé et le code natif. Utilisez une infrastructure de tests unitaires pour créer des tests unitaires, les exécuter et signaler les résultats de ces tests. Réexécutez des tests unitaires quand vous apportez des modifications pour vérifier que votre code fonctionne toujours correctement. Visual Studio Enterprise peut faire ceci automatiquement avec Live Unit Testing, qui détecte les tests affectés par les modifications de votre code et les exécute en arrière-plan au fil de votre frappe.

Les tests unitaires ont le plus d’effet sur la qualité du code quand ils font partie intégrante du flux de travail de votre développement logiciel. Dès que vous écrivez une fonction ou un autre bloc de code d’application, créez des tests unitaires pour vérifier le comportement du code en réponse aux cas standard, limite et incorrects des données d’entrée, ainsi que les hypothèses explicites ou implicites du code. Avec le développement axé sur des tests, comme vous créez les tests unitaires avant d’écrire le code, vous utilisez les tests unitaires comme documentation de conception et spécifications fonctionnelles.

L’explorateur de tests peut également exécuter des infrastructures de tests unitaires tierces et open source ayant implémenté les interfaces des composants additionnels de l’explorateur de tests. Vous pouvez ajouter la plupart de ces infrastructures via le gestionnaire d’extensions de Visual Studio et la galerie Visual Studio. Pour plus d’informations, consultez Installer des frameworks de tests unitaires de tiers.

Vous pouvez générer rapidement des projets de test et méthodes de test à partir de votre code, ou créer manuellement les tests quand vous le souhaitez. Quand vous utilisez IntelliTest pour explorer code .NET, vous pouvez générer des données de test et une suite de tests unitaires. Pour chaque instruction dans le code, une entrée de test est générée pour exécuter cette instruction. Découvrez comment générer des tests unitaires pour code .NET.

Bien démarrer

Pour obtenir une introduction aux tests unitaires qui vous conduit directement dans le code, consultez l’une des rubriques suivantes :

Exemple de solution de la Banque

Dans cet article, nous utilisons comme exemple le développement d’une application fictive, appelée MyBank. Vous n’avez pas besoin du code réel pour suivre les explications fournies dans cette rubrique. Les méthodes de test sont écrites en C# et présentées à l’aide du framework de tests unitaires Microsoft pour le code managé. Toutefois, les concepts sont facilement transférés vers d’autres langages et frameworks.

MyBank Solution 2019

MyBank Solution 2022

Notre première tentative de conception de l’application MyBank inclut un composant Accounts (Comptes) qui représente un compte individuel et ses transactions avec la banque et un composant Database (Base de données) qui correspond à la fonction d’agrégation et de gestion des comptes individuels.

Nous créons une solution Bank qui contient deux projets :

  • Accounts

  • BankDB

Notre première tentative de conception du projet Accounts comporte une classe destinée à détenir les informations de base d’un compte, une interface qui spécifie les fonctionnalités usuelles de n’importe quel type de compte, par exemple le dépôt ou le retrait d’argent sur le compte, ainsi qu’une classe dérivée de l’interface qui représente un compte courant. Nous commençons les projets Accounts (Comptes) en créant les fichiers sources suivants :

  • AccountInfo.cs définit les informations de base d’un compte.

  • IAccount.cs définit une interface IAccount standard pour un compte, y compris les méthodes pour déposer de l’argent sur un compte ou en retirer, et pour récupérer le solde du compte.

  • CheckingAccount.cs contient la classe CheckingAccount qui implémente l’interface IAccount d’un compte courant.

Nous savons par expérience qu’un retrait sur un compte courant doit s’assurer que le montant retiré est inférieur au solde du compte. Aussi, nous remplaçons la méthode IAccount.Withdraw de CheckingAccount par une méthode qui vérifie cette condition. La méthode peut ressembler à ceci :

public void Withdraw(double amount)
{
    if(m_balance >= amount)
    {
        m_balance -= amount;
    }
    else
    {
        throw new ArgumentException(nameof(amount), "Withdrawal exceeds balance!");
    }
}

Maintenant que nous avons le code, il est temps de le tester.

Créez des projets de test unitaire et des méthodes de test (C#)

Pour C#, il est souvent plus rapide de générer le projet de test unitaire et les stubs de test unitaire à partir de votre code. Vous pouvez également choisir de créer le projet de test unitaire et les tests manuellement selon vos besoins. Si vous voulez créer des tests unitaires avec un cadre tiers, vous devrez installer l’une de ces extensions : NUnit ou xUnit. Si vous n’utilisez pas C#, ignorez cette section et accédez à Créer le projet de test unitaire et les tests unitaires manuellement.

Créer un projet de test unitaire et des stubs de test unitaire

  1. Dans la fenêtre de l’éditeur de code, cliquez avec le bouton droit et choisissez Créer des tests unitaires dans le menu contextuel.

    From the editor window, view the context menu

    Note

    La commande de menu Créer des tests unitaires est uniquement disponible pour du code C#. Pour utiliser cette méthode avec .NET Core ou .NET Standard, Visual Studio 2019 ou une version ultérieure est nécessaire.

    From the editor window, view the context menu

    Note

    La commande de menu Créer des tests unitaires est uniquement disponible pour du code C#. Pour utiliser cette méthode avec .NET Core ou .NET Standard, Visual Studio 2019 ou une version ultérieure est nécessaire.

  2. Cliquez sur OK pour accepter les valeurs par défaut pour créer vos tests unitaires, ou changez les valeurs utilisées pour créer et nommer le projet de test unitaire et les tests unitaires. Vous pouvez sélectionner le code qui est ajouté par défaut aux méthodes de test unitaire.

    Create Unit Tests dialog box in Visual Studio

    Create Unit Tests dialog box in Visual Studio

  3. Les stubs de test unitaire sont créés dans un nouveau projet de test unitaire pour toutes les méthodes dans la classe.

    The unit tests are created

    The unit tests are created

  4. Passez maintenant à l’étape suivante pour apprendre comment Rédiger vos tests pour rendre vos tests unitaires significatifs, et tous les tests unitaires supplémentaires que vous pourriez vouloir ajouter pour tester votre code de manière approfondie.

Créer le projet de test unitaire et les tests unitaires manuellement

Un projet de test unitaire reflète généralement la structure d’un seul projet de code. Dans l’exemple MyBank, vous ajoutez deux projets de test unitaire nommés AccountsTests et BankDbTests à la solution Bank . Les noms des projets de test sont arbitraires, mais l’adoption d’une convention d’affectation de noms standard est une bonne idée.

Pour ajouter un projet de test unitaire à une solution :

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur la solution et choisissez Ajouter>NouveauProjet.

  2. Saisissez test dans la zone de recherche de modèle de projet pour rechercher un modèle de projet de test unitaire pour le cadre de test que vous voulez utiliser. (Dans les exemples de cette rubrique, nous utilisons MSTest.)

  3. Dans la page suivante, nommez le projet. Pour tester le projet Accounts de notre exemple, vous pouvez le nommer AccountsTests.

  4. Dans votre projet de test unitaire, ajoutez une référence au projet de code testé : le projet Accounts (Comptes) dans notre exemple.

    Pour créer la référence au projet de code :

    1. Dans le projet de test unitaire dans l’Explorateur de solutions, faites un clic droit sur le nœud Références ou Dépendances , puis choisissez Ajouter une référence de projet ou Ajouter une référence, selon ce qui est disponible.

    2. Dans la boîte de dialogue Gestionnaire de références, ouvrez le nœud Solution et choisissez Projets. Sélectionnez le nom du projet de code et fermez la boîte de dialogue.

Chaque projet de test unitaire contient les classes qui reflètent les noms des classes du projet de code. Dans notre exemple, le projet AccountsTests contient les classes suivantes :

  • la classeAccountInfoTests contient les méthodes de test unitaire pour la classe AccountInfo du projet Accounts ;

  • la classeCheckingAccountTests contient les méthodes de test unitaire pour la classe CheckingAccount .

Écrire vos tests

L’infrastructure de tests unitaires que vous utilisez et Visual Studio IntelliSense vous guident lors de l’écriture du code des tests unitaires pour un projet de code. Pour s’exécuter dans l’explorateur de tests, la plupart des infrastructures nécessitent que vous ajoutiez des attributs spécifiques pour identifier les méthodes de test unitaire. Les infrastructures fournissent également un moyen, généralement par le biais d’instructions assert ou d’attributs de méthode, pour indiquer si la méthode de test a réussi ou échoué. D’autres attributs identifient les méthodes facultatives d’installation lors de l’initialisation des classes et avant chaque méthode de test, ainsi que les méthodes de démontage qui sont exécutées après chaque méthode de test et avant la destruction de la classe.

Le modèle AAA (Arrange, Act, Assert) est un moyen couramment utilisé pour écrire les tests unitaires d’une méthode testée.

  • La section Arrange d’une méthode de test unitaire initialise les objets et définit la valeur des données transmises à la méthode testée.

  • La section Act appelle la méthode testée avec les paramètres triés.

  • La section Assert vérifie que l’action de la méthode testée se comporte comme prévu. Pour .NET, les méthodes de la classe Assert sont souvent utilisées pour la vérification.

Pour tester la méthode CheckingAccount.Withdraw de notre exemple, nous pouvons écrire deux tests : un qui vérifie le comportement standard de la méthode et un qui vérifie qu’un retrait supérieur au solde échouera (Le code suivant montre un test unitaire MSTest, pris en charge dans .NET.). Dans la classe CheckingAccountTests , nous ajoutons les méthodes suivantes :

[TestMethod]
public void Withdraw_ValidAmount_ChangesBalance()
{
    // arrange
    double currentBalance = 10.0;
    double withdrawal = 1.0;
    double expected = 9.0;
    var account = new CheckingAccount("JohnDoe", currentBalance);

    // act
    account.Withdraw(withdrawal);

    // assert
    Assert.AreEqual(expected, account.Balance);
}

[TestMethod]
public void Withdraw_AmountMoreThanBalance_Throws()
{
    // arrange
    var account = new CheckingAccount("John Doe", 10.0);

    // act and assert
    Assert.ThrowsException<System.ArgumentException>(() => account.Withdraw(20.0));
}

Pour plus d’informations sur les infrastructures de tests unitaires Microsoft, consultez l’une des rubriques suivantes :

Définir des délais d’attente pour les tests unitaires

Si vous utilisez le framework MSTest, vous pouvez utiliser TimeoutAttribute pour définir un délai d’attente sur une méthode de test individuelle :

[TestMethod]
[Timeout(2000)]  // Milliseconds
public void My_Test()
{ ...
}

Pour affecter au délai d’attente la valeur maximale autorisée :

[TestMethod]
[Timeout(TestTimeout.Infinite)]  // Milliseconds
public void My_Test ()
{ ...
}

Exécuter des tests dans l’explorateur de tests

Quand vous générez le projet de test, les tests s’affichent dans l’explorateur de tests. Si l’explorateur de tests n’est pas visible, sélectionnez Test dans le menu Visual Studio et choisissez Fenêtres, puis Explorateur de tests (ou appuyez sur Ctrl + E, T).

Unit Test Explorer

Unit Test Explorer

À mesure que vous exécutez, écrivez et réexécutez vos tests, l’Explorateur de tests peut afficher les résultats dans les groupes Échecs de tests, Tests réussis, Tests ignorés et Tests non exécutés. Différentes options de regroupement sont disponibles dans la barre d’outils.

Vous pouvez également filtrer les tests de n’importe quelle vue sur le texte de la zone de recherche au niveau global ou en sélectionnant l’un des filtres prédéfinis. Vous pouvez exécuter une sélection des tests à tout moment. Les résultats d’une série de tests sont immédiatement visibles dans la barre réussite/échec en haut de la fenêtre de l’explorateur. Les détails d’un résultat de méthode de test sont affichés quand vous sélectionnez le test.

Exécuter et afficher des tests

La barre d’outils de l’explorateur de tests vous permet de découvrir, d’organiser et d’exécuter les tests qui vous intéressent.

Run tests from the Test Explorer toolbar

Run tests from the Test Explorer toolbar

Vous pouvez choisir Tout exécuter pour exécuter tous vos tests (ou appuyez sur Ctrl + R, V), ou choisir Exécuter pour choisir un sous-ensemble de tests à exécuter (Ctrl + R, T). Sélectionnez un test pour en afficher les spécificités dans le volet de détails. Choisissez Ouvrir un test dans le menu contextuel (clavier :F12) pour afficher le code source du test sélectionné.

Si les tests individuels n’ont aucune dépendance qui les empêche d’être exécutés dans n’importe quel ordre, activez l’exécution parallèle des tests dans le menu Paramètres de la barre d’outils. Cela peut réduire sensiblement le temps nécessaire pour exécuter tous les tests.

Exécuter des tests après chaque génération

Pour exécuter vos tests unitaires après chaque build locale, ouvrez l’icône des paramètres dans la barre d’outils de l’Explorateur de tests, puis sélectionnez Exécuter les tests après la build.

Regrouper et filtrer la liste de tests

Quand vous avez un grand nombre de tests, vous pouvez taper du texte dans la zone de recherche de l’Explorateur de tests pour filtrer la liste selon la chaîne spécifiée. Vous pouvez limiter votre filtre encore plus en choisissant parmi la liste des filtres.

Search filter categories

Search filter categories

Button Description
Test Explorer group button Pour regrouper vos tests par catégorie, choisissez le bouton Grouper par .

Pour plus d’informations, consultez Exécuter des tests unitaires avec l’Explorateur de tests.

Q&A

Q : Comment déboguer des tests unitaires ?

R : Utilisez l’explorateur de tests pour démarrer une session de débogage de vos tests. L’exécution pas à pas de votre code avec le débogueur Visual Studio vous conduit de manière transparente à des allers et retours entre les tests unitaires et le projet testé. Pour démarrer le débogage :

  1. Dans l’éditeur Visual Studio, définissez un point d’arrêt dans une ou plusieurs méthodes de test que vous souhaitez déboguer.

    Notes

    Comme les méthodes de test peuvent s’exécuter dans n’importe quel ordre, définissez les points d’arrêt dans toutes les méthodes de test que vous souhaitez déboguer.

  2. Dans l’explorateur de tests, sélectionnez les méthodes de test, puis choisissez Déboguer les tests sélectionnés dans le menu contextuel.

En savoir plus sur le débogage des tests unitaires.

Q : Si j’utilise le développement axé sur des tests, comment générer du code à partir de mes tests ?

A : Utilisez Actions rapides pour générer des classes et des méthodes dans votre code de projet. Écrivez une instruction dans une méthode de test qui appelle la classe ou la méthode que vous souhaitez générer, puis ouvrez l’ampoule qui apparaît sous l’erreur. Si l’appel concerne un constructeur de la nouvelle classe, choisissez Générer le type dans le menu et suivez l’Assistant pour insérer la classe dans votre projet de code. Si l’appel concerne une méthode, choisissez Générer la méthode à partir du menu IntelliSense.

Generate Method Stub Quick Action Menu

Generate Method Stub Quick Action Menu

Q : Puis-je créer des tests unitaires qui utilisent plusieurs groupes de données en entrée pour exécuter le test ?

R : Oui. Lesméthodes de test pilotées par les données vous permettent de tester une plage de valeurs avec une méthode de test unitaire unique. Utilisez un attribut DataRow, DynamicData ou DataSource pour la méthode de test qui spécifie la source de données contenant les valeurs des variables que vous voulez tester.

La méthode attribuée s’exécute une fois pour chaque ligne de la source de données. L’explorateur de tests indique un échec du test de la méthode si l’une des itérations échoue. Le volet Détails des résultats du test de la méthode vous indique le statut réussite/échec pour chaque ligne de données.

En savoir plus sur les tests unitaires pilotés par les données.

Q : Puis-je afficher la quantité de code testée par mes tests unitaires ?

R : Oui. Vous pouvez déterminer la quantité de code qui est réellement testée par vos tests unitaires à l’aide de l’outil de couverture du code Visual Studio dans Visual Studio Enterprise. Les langages natifs et managés ainsi que toutes les infrastructures de tests unitaires qui peuvent être exécutés par l’infrastructure de tests unitaires sont pris en charge.

Vous pouvez exécuter la couverture de code sur les tests sélectionnés ou sur tous les tests d'une solution. La fenêtre Résultats de la couverture du code affiche le pourcentage des blocs du code du produit qui ont été testés par ligne, fonction, classe, espace de noms et module.

Pour exécuter la couverture du code pour les méthodes de test dans une solution, choisissez Test>Analyser la couverture de code pour tous les tests.

Les résultats de la couverture apparaissent dans la fenêtre Résultats de la couverture du code.

Code coverage results

Code coverage results

En savoir plus sur la couverture du code.

Q : Puis-je tester des méthodes de mon code qui ont des dépendances externes ?

R : Oui. Si vous disposez de Visual Studio Enterprise, Microsoft Fakes peut être utilisé avec les méthodes de test que vous écrivez à l’aide des infrastructures de tests unitaires pour le code managé.

Microsoft Fakes utilise deux approches pour créer des classes de substitution pour les dépendances externes :

  1. Lesstubs génèrent des classes de substitution dérivées de l’interface parente de la classe de dépendance cible. Les méthodes stub peuvent être remplacées par des méthodes virtuelles publiques de la classe cible.

  2. Lesshims utilisent l’instrumentation du runtime pour rediriger les appels à une méthode cible vers une méthode shim de substitution pour les méthodes non virtuelles.

Dans les deux approches, vous utilisez les délégués générés des appels à la méthode de dépendance pour spécifier le comportement souhaité dans la méthode de test.

En savoir plus sur l’ isolement des méthodes de test unitaire avec Microsoft Fakes.

Q : Puis-je utiliser d’autres infrastructures de tests unitaires pour créer des tests unitaires ?

R : Oui, suivez ces étapes pour rechercher et installer d’autres frameworks. Après le redémarrage de Visual Studio, rouvrez votre solution pour créer vos tests unitaires, puis sélectionnez vos frameworks installés ici :

Select other installed unit test framework

Vos stubs de test unitaire seront créés à l’aide de l’infrastructure sélectionnée.