Freigeben über


Komponententests C# in .NET mit dotnet-Test und xUnit

In diesem Tutorial wird gezeigt, wie Sie eine Lösung erstellen, die ein Unit-Test-Projekt und ein Quellcodeprojekt enthält. Um dem Lernprogramm mithilfe einer vordefinierten Lösung zu folgen, zeigen Sie den Beispielcode an, oder laden Sie den Beispielcode herunter. Anweisungen zum Herunterladen finden Sie unter Beispiele und Lernprogramme.

Erstellen der Lösung

In diesem Abschnitt wird eine Lösung erstellt, die die Quell- und Testprojekte enthält. Die fertige Lösung hat die folgende Verzeichnisstruktur:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService
        PrimeService.cs
        PrimeService.csproj
    /PrimeService.Tests
        PrimeService_IsPrimeShould.cs
        PrimeServiceTests.csproj

Die folgenden Anweisungen enthalten die Schritte zum Erstellen der Testlösung. Anweisungen zum Erstellen der Testlösung finden Sie unter "Befehle ", um die Testlösung in einem Schritt zu erstellen.

  • Öffnen eines Shell-Fensters.

  • Führen Sie den folgenden Befehl aus:

    dotnet new sln -o unit-testing-using-dotnet-test
    

    Der dotnet new sln Befehl erstellt eine neue Lösung im Verzeichnis "Unit-testing-using-dotnet-test" .

  • Ändern Sie das Verzeichnis in unit-testing-using-dotnet-test.

  • Führen Sie den folgenden Befehl aus:

    dotnet new classlib -o PrimeService
    

    Der dotnet new classlib Befehl erstellt ein neues Klassenbibliotheksprojekt im Ordner "PrimeService ". Die neue Klassenbibliothek enthält den zu testenden Code.

  • Benennen Sie Class1.cs in PrimeService.cs um.

  • Ersetzen Sie den Code in PrimeService.cs durch den folgenden Code:

    using System;
    
    namespace Prime.Services
    {
        public class PrimeService
        {
            public bool IsPrime(int candidate)
            {
                throw new NotImplementedException("Not implemented.");
            }
        }
    }
    

    Derzeit wirft dieser Code ein NotImplementedException, aber Sie werden die Methode später im Tutorial implementieren.

  • Führen Sie im Verzeichnis " Unit-testing-using-dotnet-test" den folgenden Befehl aus, um der Lösung das Klassenbibliotheksprojekt hinzuzufügen:

    dotnet sln add ./PrimeService/PrimeService.csproj
    
  • Erstellen Sie das Projekt "PrimeService.Tests ", indem Sie den folgenden Befehl ausführen:

    dotnet new xunit -o PrimeService.Tests
    

    Mit dem vorherigen Befehl wird das Projekt "PrimeService.Tests " im Verzeichnis "PrimeService.Tests " erstellt. Das Testprojekt verwendet xUnit als Testbibliothek. Der Befehl konfiguriert außerdem den Testläufer, indem der Projektdatei die folgenden <PackageReference />Elemente hinzugefügt werden:

    • Microsoft.NET.Test.Sdk
    • xunit
    • xunit.runner.visualstudio
    • coverlet.collector
  • Fügen Sie das Testprojekt der Projektmappendatei hinzu, indem Sie den folgenden Befehl ausführen:

    dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj
    
  • Fügen Sie die PrimeService Klassenbibliothek als Abhängigkeit zum Projekt PrimeService.Tests hinzu:

    dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
    

Befehle zum Erstellen der Lösung

In diesem Abschnitt werden alle Befehle im vorherigen Abschnitt zusammengefasst. Überspringen Sie diesen Abschnitt, wenn Sie die Schritte im vorherigen Abschnitt abgeschlossen haben.

Mit den folgenden Befehlen wird die Testlösung auf einem Windows-Computer erstellt. Aktualisieren Sie für macOS und Unix den ren Befehl auf die Betriebssystemversion, ren um eine Datei umzubenennen:

dotnet new sln -o unit-testing-using-dotnet-test
cd unit-testing-using-dotnet-test
dotnet new classlib -o PrimeService
ren .\PrimeService\Class1.cs PrimeService.cs
dotnet sln add ./PrimeService/PrimeService.csproj
dotnet new xunit -o PrimeService.Tests
dotnet add ./PrimeService.Tests/PrimeService.Tests.csproj reference ./PrimeService/PrimeService.csproj
dotnet sln add ./PrimeService.Tests/PrimeService.Tests.csproj

Folgen Sie den Anweisungen für "Ersetzen des Codes in PrimeService.cs durch den folgenden Code" im vorherigen Abschnitt.

Einen Test erstellen

Ein beliebter Ansatz bei der testgesteuerten Entwicklung (TDD) besteht darin, einen (fehlerhaften) Test zu schreiben, bevor der Zielcode implementiert wird. In diesem Lernprogramm wird der TDD-Ansatz verwendet. Die IsPrime Methode kann aufgerufen, aber nicht implementiert werden. Ein Testaufruf von IsPrime schlägt fehl. Bei TDD schreiben Sie einen Test, der bekanntermaßen fehlschlägt. Anschließend aktualisieren Sie den Zielcode so, dass der Testdurchlauf erfolgreich ist. Sie wiederholen diesen Ansatz, schreiben einen fehlerhaften Test und aktualisieren dann den Zielcode, um den Test zu bestehen.

Aktualisieren Sie das Projekt PrimeService.Tests :

  • Löschen Sie PrimeService.Tests/UnitTest1.cs.

  • Erstellen Sie eine Datei "PrimeService.Tests/PrimeService_IsPrimeShould.cs ".

  • Ersetzen Sie den Code in PrimeService_IsPrimeShould.cs durch den folgenden Code:

    using Xunit;
    using Prime.Services;
    
    namespace Prime.UnitTests.Services
    {
        public class PrimeService_IsPrimeShould
        {
            [Fact]
            public void IsPrime_InputIs1_ReturnFalse()
            {
                var primeService = new PrimeService();
                bool result = primeService.IsPrime(1);
    
                Assert.False(result, "1 should not be prime");
            }
        }
    }
    

Das [Fact] Attribut deklariert eine Testmethode, die vom Testläufer ausgeführt wird. Führen Sie im Ordner PrimeService.Tests den Befehl dotnet test aus. Der Dotnet-Testbefehl erstellt beide Projekte und führt die Tests aus. Der xUnit-Testläufer enthält den Programmeinstiegspunkt zum Ausführen der Tests. dotnet test startet den Test Runner mithilfe des Komponententestprojekts.

Der Test schlägt fehl, weil IsPrime nicht implementiert wurde. Schreiben Sie mit dem TDD-Ansatz nur genügend Code, damit dieser Test erfolgreich ist. Aktualisieren Sie IsPrime mit folgendem Code:

public bool IsPrime(int candidate)
{
    if (candidate == 1)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

Führen Sie dotnet test aus. Der Test verläuft erfolgreich.

Hinzufügen weiterer Tests

Fügen Sie Primzahlentests für 0 und -1 hinzu. Sie können den im vorherigen Schritt erstellten Test kopieren und Kopien des folgenden Codes erstellen, um 0 und -1 zu testen. Aber machen Sie es nicht, da es eine bessere Möglichkeit gibt.

var primeService = new PrimeService();
bool result = primeService.IsPrime(1);

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

Das Kopieren von Testcode, wenn sich nur ein Parameter ändert, führt zu Codeduplizierung und Testblähung. Die folgenden xUnit-Attribute ermöglichen das Schreiben einer Reihe ähnlicher Tests:

  • [Theory] stellt eine Reihe von Tests dar, die denselben Code ausführen, aber unterschiedliche Eingabeargumente haben.
  • [InlineData] Attribut gibt Werte für diese Eingaben an.

Anstatt neue Tests zu erstellen, wenden Sie die vorherigen xUnit-Attribute an, um eine einzelne Theorie zu erstellen. Ersetzen Sie den folgenden Code...

[Fact]
public void IsPrime_InputIs1_ReturnFalse()
{
    var primeService = new PrimeService();
    bool result = primeService.IsPrime(1);

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

... mit folgendem Code:

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

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

Im vorangehenden Code ermöglichen [Theory] und [InlineData] das Testen mehrerer Werte, die kleiner als 2 sind. Zwei ist die kleinste Primzahl.

Fügen Sie den folgenden Code nach der Klassendeklaration und vor dem [Theory] Attribut hinzu:

private readonly PrimeService _primeService;

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

Führen Sie dotnet testaus, und zwei der Tests schlagen fehl. Um alle Tests erfolgreich zu machen, aktualisieren Sie die IsPrime Methode mit dem folgenden Code:

public bool IsPrime(int candidate)
{
    if (candidate < 2)
    {
        return false;
    }
    throw new NotImplementedException("Not fully implemented.");
}

Fügen Sie nach dem TDD-Ansatz weitere fehlerhafte Tests hinzu, und aktualisieren Sie dann den Zielcode. Sehen Sie sich die fertige Version der Tests und die vollständige Implementierung der Bibliothek an.

Die abgeschlossene IsPrime Methode ist kein effizienter Algorithmus zum Testen der Primalität.

Weitere Ressourcen