Utiliser le framework MSTest dans les tests unitaires

Le framework MSTest prend en charge les tests unitaires dans Visual Studio. Utilisez les classes et les membres dans l’espace de noms Microsoft.VisualStudio.TestTools.UnitTesting lorsque vous codez des tests unitaires. Vous pouvez également les utiliser lorsque vous affinez un test unitaire qui a été généré à partir du code.

Membres du framework

Pour fournir une vue d’ensemble plus claire du framework de test unitaire, cette section présente les membres de l’espace de noms Microsoft.VisualStudio.TestTools.UnitTesting sous forme de groupes de fonctionnalités connexes.

Notes

Les éléments d’attributs, dont les noms se terminent par « Attribute », peuvent être utilisés avec ou sans « Attribute » à la fin et, pour les constructeurs sans paramètre, avec ou sans parenthèses. Par exemple, les exemples de code suivants fonctionnent de manière identique :

[TestClass()]

[TestClassAttribute()]

[TestClass]

[TestClassAttribute]

Attributs utilisés pour identifier les classes et méthodes de test

Chaque classe de test doit avoir l’attribut TestClass, et chaque méthode de test doit avoir l’attribut TestMethod. Pour plus d’informations, consultez Anatomie d’un test unitaire.

TestClassAttribute

L’attribut TestClass marque une classe qui contient des tests et, éventuellement, des méthodes d’initialisation ou de nettoyage.

Cet attribut peut être étendu pour mettre à jour ou étendre le comportement.

Exemple :

[TestClass]
public class MyTestClass
{    
}

TestMethodAttribute

L’attribut TestMethod est utilisé à l’intérieur d’une TestClass pour définir la méthode de test réelle à exécuter.

La méthode doit être une méthode d’instance définie comme public void ou public Task (éventuellement async), et être sans paramètre.

Exemple

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public void TestMethod()
    {
    }
}
[TestClass]
public class MyTestClass
{
    [TestMethod]
    public async Task TestMethod()
    {
    }
}

Attributs utilisés pour les tests pilotés par des données

Utilisez les éléments suivants pour configurer des tests unitaires pilotés par les données. Pour plus d’informations, consultez Créer un test unitaire piloté par les données et Utiliser un fichier de configuration pour définir une source de données.

DataRow

Le DataRowAttribute vous permet de fournir des données inline utilisées lors de l’appel de la méthode de test. Il peut apparaître une ou plusieurs fois sur une méthode de test. Il doit être combiné avec TestMethodAttribute ou DataTestMethodAttribute.

Le nombre et les types d’arguments doivent correspondre exactement à la signature de la méthode de test.

Exemples d’appels valides :

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, "message", true, 2.0)]
    public void TestMethod1(int i, string s, bool b, float f) {}
    
    [TestMethod]
    [DataRow(new string[] { "line1", "line2" })]
    public void TestMethod2(string[] lines) {}

    [TestMethod]
    [DataRow(null)]
    public void TestMethod3(object o) {}

    [TestMethod]
    [DataRow(new string[] { "line1", "line2" }, new string[] { "line1.", "line2." })]
    public void TestMethod4(string[] input, string[] expectedOutput) {}
}

Notez que vous pouvez également utiliser la fonctionnalité params pour capturer plusieurs entrées du DataRow.

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2, 3, 4)]
    public void TestMethod(params int[] values) {}
}

Exemples de combinaisons non valides :

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2)] // Not valid, we are passing 2 inline data but signature expects 1
    public void TestMethod1(int i) {}

    [TestMethod]
    [DataRow(1)] // Not valid, we are passing 1 inline data but signature expects 2
    public void TestMethod2(int i, int j) {}

    [TestMethod]
    [DataRow(1)] // Not valid, count matches but types do not match
    public void TestMethod3(string s) {}
}

Notes

À compter de MSTest v3, lorsque vous souhaitez passer exactement deux tableaux, vous n’avez plus besoin d’encapsuler le deuxième tableau dans un tableau d’objets. Avant : [DataRow(new string[] { "a" }, new object[] { new string[] { "b" } })] In v3 onward: [DataRow(new string[] { "a" }, new string[] { "b" })]

Vous pouvez modifier le nom d’affichage utilisé dans Visual Studio et les enregistreurs d’événements pour chaque instance de DataRowAttribute en définissant la propriété DisplayName.

[TestClass]
public class TestClass
{
    [TestMethod]
    [DataRow(1, 2, DisplayName= "Functional Case FC100.1")]
    public void TestMethod(int i, int j) {}
}

Vous pouvez également créer votre propre attribut de ligne de données spécialisé en héritant de DataRowAttribute.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomDataRowAttribute : DataRowAttribute
{
}

[TestClass]
public class TestClass
{
    [TestMethod]
    [MyCustomDataRow(1)]
    public void TestMethod(int i) {}
}

Attributs utilisés pour fournir l’initialisation et les nettoyages

Une méthode décorés avec l’un des attributs suivants est appelée au moment spécifié. Pour plus d’informations, consultez Anatomie d’un test unitaire.

Assembly

AssemblyInitialize est appelée juste après le chargement de votre assembly, et AssemblyCleanup est appelée juste avant son déchargement.

Les méthodes marquées avec ces attributs doivent être définies comme static void ou static Task, dans une TestClass, et n’apparaissent qu’une seule fois. La partie initialisation nécessite un argument de type TestContext, et la partie nettoyage aucun argument.

[TestClass]
public class MyTestClass
{
    [AssemblyInitialize]
    public static void AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static void AssemblyCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [AssemblyInitialize]
    public static async Task AssemblyInitialize(TestContext testContext)
    {
    }

    [AssemblyCleanup]
    public static async Task AssemblyCleanup()
    {
    }
}

Classe

ClassInitialize est appelée juste avant le chargement de votre classe (mais après le constructeur statique) et ClassCleanup juste après le déchargement de votre classe.

Il est possible de contrôler le comportement d’héritage, uniquement pour la classe actuelle à l’aide de InheritanceBehavior.None ou pour toutes les classes dérivées à l’aide de InheritanceBehavior.BeforeEachDerivedClass.

Il est également possible de configurer si le nettoyage de classe doit être exécuté à la fin de la classe ou à la fin de l’assembly (cela n’est plus pris en charge à partir de MSTest v4, car EndOfClass est l’option par défaut et le seul comportement de nettoyage de classe).

Les méthodes marquées avec ces attributs doivent être définies comme static void ou static Task, dans une TestClass, et n’apparaissent qu’une seule fois. La partie initialisation nécessite un argument de type TestContext, et la partie nettoyage aucun argument.

[TestClass]
public class MyTestClass
{
    [ClassInitialize]
    public static void ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static void ClassCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [ClassInitialize]
    public static async Task ClassInitialize(TestContext testContext)
    {
    }

    [ClassCleanup]
    public static async Task ClassCleanup()
    {
    }
}

Test

TestInitialize est appelée juste avant le démarrage de votre test, et TestCleanup juste après la fin du test.

TestInitialize est similaire au constructeur de classe, mais convient généralement mieux aux initialisations longues ou asynchrones. TestInitialize est toujours appelée après le constructeur, et appelée pour chaque test (y compris chaque ligne de données de tests pilotés par des données).

TestCleanup est similaire à la classe Dispose (ou DisposeAsync), mais convient généralement mieux aux nettoyages longs ou asynchrones. TestCleanup est toujours appelée juste avant DisposeAsync/Dispose, et appelée pour chaque test (y compris chaque ligne de données de tests pilotés par des données).

Les méthodes marquées avec ces attributs doivent être définies comme void ou Task, dans une TestClass, sans paramètre, et apparaître une ou plusieurs fois.

[TestClass]
public class MyTestClass
{
    [TestInitialize]
    public void TestInitialize()
    {
    }

    [TestCleanup]
    public void TestCleanup()
    {
    }
}
[TestClass]
public class MyOtherTestClass
{
    [TestInitialize]
    public async Task TestInitialize()
    {
    }

    [TestCleanup]
    public async Task TestCleanup()
    {
    }
}

Les tests unitaires permettent de vérifier le comportement d’une application spécifique à l’aide de différents genres d’assertions, d’exceptions et d’attributs. Pour plus d’informations, consultez Utilisation des classes Assert.

Classe TestContext

Les attributs suivants et les valeurs qui leur sont assignées apparaissent dans la fenêtre Propriétés de Visual Studio pour une méthode de test particulière. Ces attributs ne sont pas censés être accessibles via le code du test unitaire. Au lieu de cela, ils affectent les façons dont le test unitaire est utilisé ou exécuté, par vous via l’IDE de Visual Studio ou par le moteur de test de Visual Studio. Par exemple, certains de ces attributs apparaissent sous forme de colonnes dans la fenêtre Test Manager et la fenêtre Résultats des tests, ce qui signifie que vous pouvez les utiliser pour regrouper et trier les tests et les résultats des tests. C’est le cas de TestPropertyAttribute, le genre d’attribut qui vous permet d’ajouter des métadonnées arbitraires aux tests unitaires. Par exemple, vous pouvez l’utiliser pour stocker le nom d’une « étape de test » couverte par ce test, en marquant le test unitaire avec [TestProperty("TestPass", "Accessibility")]. Vous pouvez également l’utiliser pour stocker un indicateur du genre de test avec [TestProperty("TestKind", "Localization")]. La propriété que vous créez à l’aide de cet attribut et la valeur de propriété que vous assignez sont affichées dans la fenêtre Propriétés de Visual Studio sous le titre Spécifique au test.

DeploymentItemAttribute

Le framework MSTest V2 a introduit DeploymentItemAttribute pour copier des fichiers ou des dossiers spécifiés comme éléments de déploiement dans le répertoire de déploiement (si vous n’ajoutez pas de chemin de sortie personnalisé, les fichiers sont copiés dans le dossier TestResults à l’intérieur du dossier du projet). Le répertoire de déploiement regroupe tous les éléments de déploiement ainsi que la DLL du projet de test.

Vous pouvez l’utiliser sur des classes de test (marquées avec l’attribut TestClass) ou sur des méthodes de test (marquées avec l’attribut TestMethod).

Les utilisateurs peuvent avoir plusieurs instances de l’attribut pour spécifier plusieurs éléments.

Et ici, vous pouvez voir ses constructeurs.

Exemple

[TestClass] 
[DeploymentItem(@"C:\classLevelDepItem.xml")]   // Copy file using some absolute path
public class UnitTest1
{
    [TestMethod]
    [DeploymentItem(@"..\..\methodLevelDepItem1.xml")]   // Copy file using a relative path from the dll output location
    [DeploymentItem(@"C:\DataFiles\methodLevelDepItem2.xml", "SampleDataFiles")]   // File will be added under a SampleDataFiles in the deployment directory
    public void TestMethod1()
    {
        string textFromFile = File.ReadAllText("classLevelDepItem.xml");
    }
}

Classes de configuration de test

Attributs utilisés pour générer des rapports

Les attributs de cette section lient la méthode de test qu’ils décorent aux entités de la hiérarchie de projet d’un projet d’équipe Team Foundation Server.

Classes utilisées avec des accesseurs private

Vous pouvez générer un test unitaire pour une méthode privée. Cette génération crée une classe d’accesseur private, qui instancie un objet de la classe PrivateObject. La classe PrivateObject est une classe wrapper qui utilise la réflexion dans le cadre du processus d’accesseur private. La classe PrivateType est similaire, mais elle est utilisée pour appeler des méthodes statiques privées au lieu d’appeler des méthodes d’instance privées.

Voir aussi