Komponententests für C# mit MSTest und .NET

Dieses Tutorial führt Sie interaktiv Schritt für Schritt durch das Erstellen einer Beispielprojektmappe, um die Konzepte von Komponententests zu erlernen. Wenn Sie dem Tutorial lieber mit einer vorgefertigten Projektmappe folgen, zeigen Sie den Beispielcode an, oder laden Sie ihn herunter, bevor Sie beginnen. Anweisungen zum Herunterladen finden Sie unter Beispiele und Lernprogramme.

Dieser Artikel befasst sich mit dem Testen eines .NET Core-Projekts. Wenn Sie ein ASP.NET Core-Projekt testen, finden Sie weitere Informationen unter Integrationstests in ASP.NET Core.

Voraussetzungen

Erstellen des Quellprojekts

Öffnen eines Shell-Fensters. Erstellen Sie ein Verzeichnis namens unit-testing-using-mstest, um darin die Projektmappe zu speichern. Führen Sie in diesem neuen Verzeichnis dotnet new sln aus, um eine neue Projektmappendatei für die Klassenbibliothek und das Testprojekt zu erstellen. Erstellen Sie ein PrimeService-Verzeichnis. Die folgende Gliederung zeigt die Verzeichnis- und Dateistruktur:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService

Machen Sie PrimeService zum aktuellen Verzeichnis, und führen Sie dotnet new classlib aus, um das Quellprojekt zu erstellen. Benennen Sie Class1.cs in PrimeService.cs um. Ersetzen Sie den Code in der Datei durch den folgenden Code, um eine fehlerhafte Implementierung der PrimeService-Klasse zu erstellen:

using System;

namespace Prime.Services
{
    public class PrimeService
    {
        public bool IsPrime(int candidate)
        {
            throw new NotImplementedException("Please create a test first.");
        }
    }
}

Ändern Sie das Verzeichnis wieder in das Verzeichnis unit-testing-using-mstest. Führen Sie dotnet sln add aus, um das Klassenbibliotheksprojekt zur Projektmappe hinzuzufügen:

dotnet sln add PrimeService/PrimeService.csproj

Erstellen des Testprojekts

Erstellen Sie das Verzeichnis PrimeService.Tests. Die folgende Gliederung zeigt die Verzeichnisstruktur:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests

Machen Sie das PrimeService.Tests-Verzeichnis zum aktuellen Verzeichnis, und erstellen Sie ein neues Projekt mit dotnet new mstest. Der neue dotnet-Befehl erstellt ein Testprojekt, das MSTest als Testbibliothek verwendet. Die Vorlage konfiguriert das Test Runner-Tool in der Datei PrimeServiceTests.csproj:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
  <PackageReference Include="MSTest.TestAdapter" Version="2.1.1" />
  <PackageReference Include="MSTest.TestFramework" Version="2.1.1" />
  <PackageReference Include="coverlet.collector" Version="1.3.0" />
</ItemGroup>

Für das Testprojekt sind weitere Pakete zum Erstellen und Ausführen von Unittests erforderlich. Im vorherigen Schritt hat dotnet new das MSTest SDK, das MSTest-Testframework, den MSTest-Runner und das Coverlet für die Code Coverage-Berichterstellung.

Fügen Sie die PrimeService-Klassenbibliothek als weitere Abhängigkeit zum Projekt hinzu. Verwenden Sie den Befehl dotnet add reference:

dotnet add reference ../PrimeService/PrimeService.csproj

Die ganze Datei finden Sie im Beispielerepository auf GitHub.

Die folgende Gliederung zeigt das endgültige Projektmappenlayout:

/unit-testing-using-mstest
    unit-testing-using-mstest.sln
    /PrimeService
        Source Files
        PrimeService.csproj
    /PrimeService.Tests
        Test Source Files
        PrimeServiceTests.csproj

Wechseln Sie zum Verzeichnis unit-testing-using-mstest, und führen Sie dotnet sln add aus:

dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Erstellen des ersten Tests

Schreiben Sie einen fehlerhaften Test, lassen Sie ihn bestehen, und wiederholen Sie den Vorgang dann. Entfernen Sie UnitTest1.cs aus dem PrimeService.Tests-Verzeichnis, und erstellen Sie eine neue C#-Datei namens PrimeService_IsPrimeShould.cs mit folgendem Inhalt:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Prime.Services;

namespace Prime.UnitTests.Services
{
    [TestClass]
    public class PrimeService_IsPrimeShould
    {
        private readonly PrimeService _primeService;

        public PrimeService_IsPrimeShould()
        {
            _primeService = new PrimeService();
        }

        [TestMethod]
        public void IsPrime_InputIs1_ReturnFalse()
        {
            bool result = _primeService.IsPrime(1);

            Assert.IsFalse(result, "1 should not be prime");
        }
    }
}

Das TestClass-Attribut gibt eine Klasse an, die Komponententests enthält. Das TestMethod-Attribut gibt an, dass es sich bei einer Methode um eine Testmethode handelt.

Speichern Sie diese Datei und führen Sie dotnet test aus, um die Tests und die Klassenbibliothek zu erstellen und anschließend die Tests auszuführen. Der MSTest Test Runner verfügt über den Programmeinstiegspunkt zum Ausführen der Tests. dotnet test startet Test Runner mithilfe des von Ihnen erstellten Komponententestprojekts.

Ihr Test schlägt fehl. Sie haben die Implementierung noch nicht erstellt. Damit dieser Test erfolgreich verläuft, schreiben Sie einen ganz einfachen Code in die PrimeService-Klasse:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Please create a test first.");
}

Führen Sie im Verzeichnis unit-testing-using-mstest erneut dotnet test aus. Der dotnet test-Befehl führt einen Build für das PrimeService-Projekt und anschließend für das PrimeService.Tests-Projekt aus. Nachdem beide Projekte erstellt wurden, wird dieser einzelne Test ausgeführt. Er ist erfolgreich.

Hinzufügen weiterer Features

Nachdem Sie dafür gesorgt haben, dass ein Test erfolgreich verläuft, schreiben Sie weiter. Es gibt einige weitere einfache Fälle für Primzahlen: 0, -1. Sie könnten neue Tests zwar mit dem TestMethod-Attribut hinzufügen, allerdings wird dies auf diese Weise schnell mühsam. Es gibt andere MSTest-Attribute, mit deren Hilfe Sie eine Reihe ähnlicher Tests schreiben können. Eine Testmethode kann denselben Code ausführen, aber unterschiedliche Eingabeargumente haben. Sie können das DataRow-Attribut verwenden, um Werte für diese Eingaben anzugeben.

Statt neue Tests zu erstellen, wenden Sie diese beiden Attribute zum Erstellen eines einzelnen datengesteuerten Tests an. Bei dem datengesteuerten Test handelt es sich um eine Methode, die mehrere Werte unter zwei als niedrigste Primzahl testet. Fügen Sie eine neue Testmethode in PrimeService_IsPrimeShould.cs hinzu:

[TestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void IsPrime_ValuesLessThan2_ReturnFalse(int value)
{
    var result = _primeService.IsPrime(value);

    Assert.IsFalse(result, $"{value} should not be prime");
}

Führen Sie dotnet test aus und zwei dieser Tests schlagen fehl. Damit alle Tests erfolgreich sind, müssen Sie in der Datei PrimeService.cs am Anfang der Methode IsPrime die if-Klausel ändern:

if (candidate < 2)

Wiederholen Sie den Vorgang, indem Sie weitere Tests, Theorien und Code in der Hauptbibliothek hinzufügen. Sie verfügen über die endgültige Version der Tests und die vollständige Implementierung der Bibliothek.

Sie haben eine kleine Bibliothek und eine Reihe von Unittests für diese Bibliothek erstellt. Sie haben die Projektmappe so strukturiert, dass das Hinzufügen neuer Pakete und Tests Teil des normalen Workflows ist. Sie haben den Großteil Ihrer Zeit und Ihres Aufwands mit der Erreichung der Anwendungsziele verbracht.

Siehe auch