Freigeben über


Erstellen eines datengesteuerten Komponententests

Sie können das Microsoft-Komponententestframework (MSTest) für verwalteten Code verwenden, um eine Komponententestmethode zum Abrufen von Werten aus einer Datenquelle einzurichten. Die Methode wird für jede Zeile in der Datenquelle nacheinander ausgeführt, wodurch es einfach ist, eine Vielzahl von Eingaben mithilfe einer einzelnen Methode zu testen.

Ein datengesteuerter Komponententest kann eine der folgenden Arten verwenden:

  • Inlinedaten mithilfe des attributs "DataRow"
  • Mitgliederdaten mithilfe des DynamicData-Attributs
  • von einigen bekannten Quellenanbieter des DataSource-Attributs

Die Methode im Test

Als Beispiel gehen wir davon aus, dass Sie folgendes haben:

  1. Eine Lösung namens MyBank, die Transaktionen für verschiedene Kontentypen akzeptiert und verarbeitet.

  2. Ein Projekt in MyBank namens BankDb, das die Transaktionen für Konten verwaltet.

  3. Eine Klasse namens Maths im BankDb Projekt, die die mathematischen Funktionen ausführt, um sicherzustellen, dass jede Transaktion für die Bank vorteilhaft ist.

  4. Ein Komponententestprojekt, das als BankDbTests bezeichnet wird, um das Verhalten der BankDb Komponente zu testen.

  5. Eine Komponententestklasse, die als MathsTests bezeichnet wird, um das Verhalten der Maths Klasse zu überprüfen.

Wir testen eine Methode in Maths, die zwei ganze Zahlen mithilfe einer Schleife hinzufügt:

public int AddIntegers(int first, int second)
{
    int sum = first;
    for (int i = 0; i < second; i++)
    {
        sum += 1;
    }

    return sum;
}

Testen der Testmethode

Auf Inline-Daten gestützter Test

Bei Inlinetests verwendet MSTest DataRow zum Angeben von Werten, die vom datengesteuerten Test verwendet werden. Der Test in diesem Beispiel wird für jede Datenzeile nacheinander ausgeführt.

[TestMethod]
[DataRow(1, 1, 2)]
[DataRow(2, 2, 4)]
[DataRow(3, 3, 6)]
[DataRow(0, 0, 1)] // The test run with this row fails
public void AddIntegers_FromDataRowTest(int x, int y, int expected)
{
    var target = new Maths();
    int actual = target.AddIntegers(x, y);
    Assert.AreEqual(expected, actual,
        "x:<{0}> y:<{1}>",
        new object[] {x, y});
}

Auf Memberdaten gestützter Test

MSTest verwendet DynamicData Attribut, um den Namen, die Art und den definierenden Typ (standardmäßig wird der aktuelle Typ verwendet) des Elements anzugeben, das die vom datengesteuerten Test verwendeten Daten bereitstellt.

Hinweis

Vor MSTest 3.8 bestand die DynamicDataSourceType Enumeration aus zwei Membern, Property und Method. Der Standardwert war Property. Ab MSTest 3.8 wird der Enumeration ein neues Element AutoDetect hinzugefügt und ist die Standardeinstellung. Sie müssen also nicht mehr DynamicDataSourceTypeangeben.

public static IEnumerable<object[]> AdditionData
{
    get
    {
        return new[]
        { 
            new object[] { 1, 1, 2 },
            new object[] { 2, 2, 4 },
            new object[] { 3, 3, 6 },
            new object[] { 0, 0, 1 }, // The test run with this row fails
        };
    }
}

[TestMethod]
[DynamicData(nameof(AdditionData))]
public void AddIntegers_FromDynamicDataTest(int x, int y, int expected)
{
    var target = new Maths();
    int actual = target.AddIntegers(x, y);
    Assert.AreEqual(expected, actual,
        "x:<{0}> y:<{1}>",
        new object[] {x, y});
}

Es ist auch möglich, den standardmäßig generierten Anzeigenamen mithilfe der DynamicDataDisplayName-Eigenschaft des attributs DynamicData außer Kraft zu setzen. Die Signatur der Anzeigenamenmethode muss public static string sein und zwei Parameter akzeptieren, die erste vom Typ MethodInfo und das zweite vom Typ object[].

public static string GetCustomDynamicDataDisplayName(MethodInfo methodInfo, object[] data)
{
    return string.Format("DynamicDataTestMethod {0} with {1} parameters", methodInfo.Name, data.Length);
}

[DynamicData(nameof(AdditionData), DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))]

Datengesteuerter Quellanbietertest

Das Erstellen eines Datenquellengesteuerten Komponententests umfasst die folgenden Schritte:

  1. Erstellen Sie eine Datenquelle, die die Werte enthält, die Sie in der Testmethode verwenden. Die Datenquelle kann ein beliebiger Typ sein, der auf dem Computer registriert ist, auf dem der Test ausgeführt wird.

  2. Fügen Sie der Testklasse eine TestContext-Eigenschaft vom Typ TestContext hinzu, die öffentlich ist.

  3. Erstellen einer Komponententestmethode

  4. Fügen Sie ihr ein DataSourceAttribute Attribut hinzu.

  5. Verwenden Sie die DataRow Indexereigenschaft, um die Werte abzurufen, die Sie in einem Test verwenden.

Hinweis

DataSourceAttribute wird derzeit nur in .NET Framework unterstützt. Wenn Sie versuchen, in einem .NET Core-, .NET 5- (oderhöher), UWP- oder WinUI-Komponententestprojekt mit dieser Methode auf Testdaten zuzugreifen, wird ein Fehler in der Art von 'TestContext' enthält keine Definition für 'DataRow', und es konnte keine zugängliche Erweiterungsmethode 'DataRow' gefunden werden, die ein erstes Argument vom Typ 'TestContext' akzeptiert (fehlt möglicherweise eine using-Anweisung oder ein Assemblyverweis?) ausgegeben.

Erstellen einer Datenquelle

Um die AddIntegers-Methode zu testen, erstellen Sie eine Datenquelle, die einen Wertebereich für die Parameter und die Summe angibt, die Sie erwarten, dass sie zurückgegeben werden. In diesem Beispiel erstellen wir eine Sql Compact-Datenbank mit dem Namen MathsData und eine Tabelle mit dem Namen AddIntegersData, die die folgenden Spaltennamen und -werte enthält.

FirstNumber SecondNumber Summe
0 1 1
1 1 2
2 –3 –1

Hinzufügen eines TestContexts zur Testklasse

Das Komponententestframework erstellt ein TestContext Objekt zum Speichern der Datenquelleninformationen für einen datengesteuerten Test. Anschließend legt das Framework dieses Objekt als Wert der von Ihnen erstellten TestContext-Eigenschaft fest.

public TestContext TestContext { get; set; }

In Ihrer Testmethode greifen Sie über die Indexer-Eigenschaft DataRow des TestContextauf die Daten zu.

Schreiben der Testmethode

Die Testmethode für AddIntegers ist relativ einfach. Rufen Sie für jede Zeile in der Datenquelle AddIntegers mit den Spaltenwerten FirstNumber und SecondNumber als Parameter auf und vergleichen Sie den Rückgabewert mit dem Spaltenwert Summe.

[TestMethod]
[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0; Data Source=C:\Data\MathsData.sdf;", "Numbers")]
public void AddIntegers_FromDataSourceTest()
{
    var target = new Maths();

    // Access the data
    int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);
    int y = Convert.ToInt32(TestContext.DataRow["SecondNumber"]);
    int expected = Convert.ToInt32(TestContext.DataRow["Sum"]);
    int actual = target.AddIntegers(x, y);
    Assert.AreEqual(expected, actual,
        "x:<{0}> y:<{1}>",
        new object[] {x, y});
}

Angeben des DataSourceAttribute

Das attribut DataSource gibt die Verbindungszeichenfolge für die Datenquelle und den Namen der Tabelle an, die Sie in der Testmethode verwenden. Die genauen Informationen in der Verbindungszeichenfolge unterscheiden sich, je nachdem, welche Art von Datenquelle Sie verwenden. In diesem Beispiel haben wir eine SqlServerCe-Datenbank verwendet.

[DataSource(@"Provider=Microsoft.SqlServerCe.Client.4.0;Data Source=C:\Data\MathsData.sdf", "AddIntegersData")]

Vorsicht

Die Verbindungszeichenfolge kann vertrauliche Daten enthalten (z. B. ein Kennwort). Die Verbindungszeichenfolge wird im Quellcode und in der kompilierten Assembly als Klartext gespeichert. Beschränken Sie den Zugriff auf den Quellcode und die Assembly, um diese vertraulichen Informationen zu schützen.

Das DataSource-Attribut verfügt über drei Konstruktoren.

[DataSource(dataSourceSettingName)]

Ein Konstruktor mit einem Parameter verwendet Verbindungsinformationen, die in der app.config Datei für die Lösung gespeichert sind. Der dataSourceSettingsName- ist der Name des XML-Elements in der Konfigurationsdatei, das die Verbindungsinformationen angibt.

Mithilfe einer app.config Datei können Sie den Speicherort der Datenquelle ändern, ohne Änderungen am Komponententest selbst vorzunehmen. Informationen zum Erstellen und Verwenden einer app.config-Datei finden Sie unter Schritt für Schritt: Verwenden einer Konfigurationsdatei zur Definition einer Datenquelle

[DataSource(connectionString, tableName)]

Der DataSource-Konstruktor mit zwei Parametern gibt die Verbindungszeichenfolge für die Datenquelle und den Namen der Tabelle an, die die Daten für die Testmethode enthält.

Die Verbindungszeichenfolgen hängen vom Typ des Datenquellentyps ab, sollten jedoch ein Provider-Element enthalten, das den invarianten Namen des Datenanbieters angibt.

[DataSource(
    dataProvider,
    connectionString,
    tableName,
    dataAccessMethod
    )]

Verwenden von TestContext.DataRow für den Zugriff auf die Daten

Um auf die Daten in der AddIntegersData Tabelle zuzugreifen, verwenden Sie den TestContext.DataRow Indexer. DataRow ist ein DataRow-Objekt, sodass Spaltenwerte nach Index- oder Spaltennamen abgerufen werden. Da die Werte als Objekte zurückgegeben werden, konvertieren Sie sie in den entsprechenden Typ:

int x = Convert.ToInt32(TestContext.DataRow["FirstNumber"]);

Führen Sie den Test aus und zeigen Sie die Ergebnisse an.

Wenn Sie mit dem Schreiben einer Testmethode fertig sind, erstellen Sie das Testprojekt. Die Testmethode wird im Test-Explorer in der Gruppe Nicht ausgeführte Tests angezeigt. Beim Ausführen, Schreiben und erneuten Ausführen Ihrer Tests werden die Ergebnisse vom Test-Explorer in den Gruppen Fehlgeschlagene Tests, Bestandene Tests und Nicht ausgeführte Tests angezeigt. Sie können zum Ausführen aller Tests Alle ausführen auswählen. Sie können auch Ausführen auswählen, um eine Teilmenge der Tests auszuführen.

Während der Testausführung wird die Testergebnisleiste im oberen Bereich des Test-Explorers animiert. Am Ende des Testlaufs ist der Balken grün, wenn alle Tests bestanden oder rot sind, wenn eines der Tests fehlgeschlagen ist. Eine Zusammenfassung der Testausführung wird im Detailbereich unten im Test-Explorer Fenster angezeigt. Wählen Sie einen Test aus, um die Details dieses Tests im unteren Bereich anzuzeigen.

Hinweis

Es gibt ein Ergebnis für jede Datenzeile und auch ein Zusammenfassungsergebnis. Wenn alle Zeilen den Test bestehen, gibt die Zusammenfassung das Ergebnis Bestanden zurück. Wenn der Test in einer Datenzeile fehlgeschlagen ist, wird die Zusammenfassungsausführung als Fehlgeschlagenangezeigt.

Wenn Sie eine der AddIntegers_FromDataRowTest, AddIntegers_FromDynamicDataTest oder AddIntegers_FromDataSourceTest -Methode in unserem Beispiel ausgeführt haben, wird die Ergebnisleiste rot und die Testmethode wird in die Fehlgeschlagene Testsverschoben. Ein datengesteuerter Test schlägt fehl, wenn eine der iterierten Methoden aus der Datenquelle fehlschlägt. Wenn Sie einen fehlgeschlagenen datengesteuerten Test im Test-Explorer Fenster auswählen, zeigt der Detailbereich die Ergebnisse jeder Iteration an, die durch den Datenzeilenindex identifiziert wird. In unserem Beispiel scheint es, dass der AddIntegers Algorithmus keine negativen Werte richtig behandelt.

Wenn die getestete Methode korrigiert und der Test erneut ausgeführt wird, färbt sich die Ergebnisleiste grün, und die Methode wird in die Gruppe bestandene Tests verschoben.