Verwenden des MSTest-Frameworks in Komponententests

Das MSTest-Framework unterstützt Komponententests in Visual Studio. Verwenden Sie die Klassen und Member im Microsoft.VisualStudio.TestTools.UnitTesting-Namespace, wenn Sie Code für Komponententests schreiben. Sie können sie auch verwenden, wenn Sie einen Komponententest verfeinern, der aus Code generiert wurde.

Framework-Member

Für einen besseren Überblick über das Framework für Komponententests werden die Member des Microsoft.VisualStudio.TestTools.UnitTesting-Namespaces in diesem Abschnitt in Gruppen verwandter Funktionen aufgeführt.

Hinweis

Attributelemente, deren Namen mit „Attribut“ enden, können entweder mit oder ohne „Attribut“ am Ende und für parameterlose Konstruktoren mit oder ohne Klammer verwendet werden. So wird beispielsweise mit den folgenden Codebeispielen das gleiche Ergebnis erzielt:

[TestClass()]

[TestClassAttribute()]

[TestClass]

[TestClassAttribute]

Zum Angeben von Testklassen und Testmethoden verwendete Attribute

Jede Testklasse muss das TestClass-Attribut aufweisen und jede Testmethode das TestMethod-Attribut. Weitere Informationen finden Sie unter Aufbau eines Komponententests.

TestClassAttribute

Das TestClass-Attribut markiert eine Klasse, die Tests enthält und optional Methoden initialisiert oder bereinigt.

Dieses Attribut kann erweitert werden, um das Verhalten zu aktualisieren oder zu erweitern.

Beispiel:

[TestClass]
public class MyTestClass
{    
}

TestMethodAttribute

Das TestMethod-Attribut wird innerhalb eines TestClass Attributs verwendet, um die tatsächliche auszuführende Testmethode zu definieren.

Die Methode sollte eine Instanzmethode sein, die als public void oder public Task (optional async) definiert und parameterlos ist.

Beispiel

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

Für datengesteuerte Tests verwendete Attribute

Verwenden Sie die folgenden Elemente zum Einrichten eines datengesteuerten Komponententests. Weitere Informationen finden Sie unter Vorgehensweise: Erstellen eines datengesteuerten Komponententests und Verwenden einer Konfigurationsdatei zum Definieren einer Datenquelle.

DataRow

Mit dem DataRowAttribute können Sie Inlinedaten bereitstellen, die beim Aufrufen der Testmethode verwendet werden. Das Attribut kann in einer Testmethode einmal oder mehrmals verwendet werden. Es sollte mit TestMethodAttribute oder DataTestMethodAttribute kombiniert werden.

Die Anzahl von Argumenten und die Argumenttypen müssen genau mit der Testmethodensignatur übereinstimmen.

Beispiele für gültige Aufrufe:

[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) {}
}

Sie können das params-Feature auch verwenden, um mehrere Eingaben der DataRow zu erfassen.

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

Beispiele für ungültige Kombinationen:

[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) {}
}

Hinweis

Ab MSTest v3 müssen Sie, wenn Sie genau zwei Arrays übergeben möchten, das zweite Array nicht mehr in einem Objektarray umschließen. Vorher: [DataRow(new string[] { "a" }, new object[] { new string[] { "b" } })] Ab v3: [DataRow(new string[] { "a" }, new string[] { "b" })]

Sie können den in Visual Studio verwendeten Anzeigenamen und die Protokollierungen für jede Instanz von DataRowAttribute ändern, indem Sie die DisplayName-Eigenschaft festlegen.

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

Sie können durch Vererben des DataRowAttribute auch ein eigenes spezialisiertes Datenzeilenattribut erstellen.

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

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

Attribute, die zum Bereitstellen von Initialisierungen und Bereinigungen verwendet werden

Eine mit einem der folgenden Attribute versehene Methode wird zum angegebenen Zeitpunkt aufgerufen. Weitere Informationen finden Sie unter Aufbau eines Komponententests.

Assembly

AssemblyInitialize wird direkt nach dem Laden der Assembly aufgerufen und AssemblyCleanup wird direkt vor dem Entladen der Assembly aufgerufen.

Die Methoden, die mit diesen Attributen markiert sind, sollten als static void oder static Task in einer TestClass definiert und nur einmal angezeigt werden. Der Initialisierungsteil erfordert ein Argument vom Typ TestContext und die Bereinigung kein 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()
    {
    }
}

Class

ClassInitialize wird direkt vor dem Laden der Klasse (aber nach statischem Konstruktor) aufgerufen, und ClassCleanup wird direkt nach dem Entladen der Klasse aufgerufen.

Es ist möglich, das Vererbungsverhalten zu steuern: mit InheritanceBehavior.None nur für die aktuelle Klasse oder mit InheritanceBehavior.BeforeEachDerivedClass für alle abgeleiteten Klassen.

Es ist auch möglich, zu konfigurieren, ob die Klassenbereinigung am Ende der Klasse oder am Ende der Assembly ausgeführt werden soll. (Wird ab MSTest 4 nicht mehr unterstützt, da EndOfClass das Standardverhalten und auch das einzige Verhalten für die Klassenbereinigung ist.)

Die Methoden, die mit diesen Attributen gekennzeichnet sind, sollten als static void oder static Task in einer TestClass definiert und nur einmal angezeigt werden. Der Initialisierungsteil erfordert ein Argument vom Typ TestContext und die Bereinigung kein 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

TestInitializewird direkt vor dem Starten des Tests aufgerufen, und TestCleanup wird direkt nach Abschluss des Tests aufgerufen.

TestInitialize ähnelt dem Klassenkonstruktor, eignet sich jedoch in der Regel besser für lange oder asynchrone Initialisierungen. TestInitialize wird immer nach dem Konstruktor und für jeden Test aufgerufen (einschließlich jeder Datenzeile von datengesteuerten Tests).

TestCleanup ähnelt der Klasse Dispose (oder DisposeAsync), ist jedoch in der Regel für lange oder asynchrone Bereinigungen besser geeignet. TestCleanup wird immer unmittelbar vor DisposeAsync/Dispose und für jeden Test aufgerufen (einschließlich jeder Datenzeile von datengesteuerten Tests).

Die Methoden, die mit diesen Attributen gekennzeichnet sind, sollten als void oder Task in einem TestClass definiert werden, parameterlos sein und mindestens einmal vorkommen.

[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()
    {
    }
}

Im Rahmen von Komponententests kann mit verschiedenen Arten von Assertions, Ausnahmen und Attributen überprüft werden, ob sich eine Anwendung auf eine bestimmte Weise verhält. Weitere Informationen finden Sie unter Verwenden der Assert-Klassen.

Die TestContext-Klasse

Die folgenden Attribute und die diesen zugewiesenen Werte werden im Visual Studio-Eigenschaftenfenster für eine bestimmte Testmethode angezeigt. Auf diese Attribute soll nicht über den Code des Komponententests zugegriffen werden. Stattdessen beeinflussen sie, in welcher Weise der Komponententest ausgeführt wird – entweder von Ihnen über die IDE von Visual Studio oder von der Visual Studio-Test-Engine. Einige dieser Attribute werden beispielsweise im Fenster Test Manager und im Fenster Testergebnisse in Spalten angezeigt. Das bedeutet, dass Sie sie zum Gruppieren und Sortieren von Tests und Testergebnissen verwenden können. TestPropertyAttribute ist ein Attribut dieser Art. Mit ihm können beliebige Metadaten Komponententests hinzugefügt werden. Sie können es beispielsweise verwenden, um den Namen eines Testdurchlaufs zu speichern, der von diesem Test abgedeckt wird, indem Sie den Komponententest mit [TestProperty("TestPass", "Accessibility")] kennzeichnen. Alternativ können Sie es verwenden, um einen Indikator zu speichern, der die Art des Tests angibt: [TestProperty("TestKind", "Localization")]. Die Eigenschaft, die durch die Verwendung dieses Attributs erstellt wird, und der zugewiesene Eigenschaftswert werden im Visual Studio-Eigenschaftenfenster unter der Überschrift Testspezifisch angezeigt.

DeploymentItemAttribute

Im MSTest 2-Framework wurde DeploymentItemAttribute für das Kopieren von Dateien oder Ordnern eingeführt, die als Bereitstellungselemente für das Bereitstellungsverzeichnis angegeben wurden. Ohne das Hinzufügen eines benutzerdefinierten Ausgabepfads würden sich die kopierten Dateien im TestResults-Ordner innerhalb des Projektordners befinden. Im Bereitstellungsverzeichnis befinden sich alle Bereitstellungselemente und die DLL-Datei für das Testprojekt.

Es kann entweder für Testklassen (mit dem TestClass-Attribut gekennzeichnete Klassen) oder für Testmethoden (mit dem TestMethod-Attribut gekennzeichnete Methoden) verwendet werden.

Benutzer*innen können mehrere Instanzen des Attributs erstellen, um mehr als ein Element anzugeben.

Hier sehen Sie die Konstruktoren.

Beispiel

[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");
    }
}

Testkonfigurationsklassen

Attribute, die zum Generieren von Berichten verwendet werden

Die in diesem Abschnitt beschriebenen Attribute verknüpfen die Testmethode, in der sie enthalten sind, mit Entitäten in der Projekthierarchie eines Team Foundation Server-Teamprojekts.

Mit privaten Accessoren verwendete Klassen

Sie können einen Komponententest für eine private Methode generieren. Dabei wird eine private Accessor-Klasse erstellt, die ein Objekt der PrivateObject-Klasse instanziiert. Bei der PrivateObject-Klasse handelt es sich um eine Wrapperklasse, die im Rahmen des Prozesses für den privaten Accessor Reflektionen verwendet. Die PrivateType-Klasse ist ähnlich, unterscheidet sich jedoch insofern, als sie zum Aufrufen von privaten statischen Methoden statt von privaten Instanzmethoden verwendet wird.

Weitere Informationen