Komponententests für C# in .NET Core mit „dotnet test“ und xUnitUnit testing C# in .NET Core using dotnet test and xUnit

Dieses Tutorial führt Sie interaktiv Schritt für Schritt durch das Erstellen einer Beispielprojektmappe, um die Konzepte von Unittests zu erlernen.This tutorial takes you through an interactive experience building a sample solution step-by-step to learn unit testing concepts. Wenn Sie dem Tutorial lieber mit einer vorgefertigten Projektmappe folgen, zeigen Sie den Beispielcode an, oder laden Sie ihn herunter, bevor Sie beginnen.If you prefer to follow the tutorial using a pre-built solution, view or download the sample code before you begin. Anweisungen zum Herunterladen finden Sie unter Beispiele und Lernprogramme.For download instructions, see Samples and Tutorials.

Erstellen des QuellprojektsCreating the source project

Öffnen eines Shell-Fensters.Open a shell window. Erstellen Sie ein Verzeichnis namens unit-testing-using-dotnet-test, um die Projektmappe zu speichern.Create a directory called unit-testing-using-dotnet-test to hold the solution. Führen Sie in diesem neuen Verzeichnis dotnet new sln aus, um eine neue Projektmappe zu erstellen.Inside this new directory, run dotnet new sln to create a new solution. Eine Projektmappe vereinfacht die Verwaltung des Klassenbibliotheks- und des Komponententestprojekts.Having a solution makes it easier to manage both the class library and the unit test project. Erstellen Sie im Projektmappenverzeichnis ein PrimeService-Verzeichnis.Inside the solution directory, create a PrimeService directory. Die bisherige Verzeichnis- und Dateistruktur sollte folgendermaßen aussehen:The directory and file structure thus far should be as follows:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.sln
    /PrimeService

Machen Sie PrimeService zum aktuellen Verzeichnis, und führen Sie dotnet new classlib aus, um das Quellprojekt zu erstellen.Make PrimeService the current directory and run dotnet new classlib to create the source project. Benennen Sie Class1.cs in PrimeService.cs um.Rename Class1.cs to PrimeService.cs. Erstellen Sie zunächst eine fehlerhafte Implementierung der PrimeService-Klasse, um eine testgesteuerte Entwicklung (Test Driven Development, TDD) zu verwenden:To use test-driven development (TDD), you first create a failing implementation of the PrimeService class:

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-dotnet-test.Change the directory back to the unit-testing-using-dotnet-test directory.

Führen Sie dotnet sln aus, um das Klassenbibliotheksprojekt zur Projektmappe hinzuzufügen:Run the dotnet sln command to add the class library project to the solution:

dotnet sln add .\PrimeService\PrimeService.csproj

Erstellen des TestprojektsCreating the test project

Erstellen Sie als Nächstes das Verzeichnis PrimeService.Tests.Next, create the PrimeService.Tests directory. Die folgende Gliederung zeigt die Verzeichnisstruktur:The following outline shows the directory structure:

/unit-testing-using-dotnet-test
    unit-testing-using-dotnet-test.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 xunit.Make the PrimeService.Tests directory the current directory and create a new project using dotnet new xunit. Dieser Befehl erstellt ein Testprojekt, das xUnit als Testbibliothek verwendet.This command creates a test project that uses xUnit as the test library. Die generierte Vorlage konfiguriert den Test Runner in der Datei PrimeServiceTests.csproj ähnlich wie im folgenden Code:The generated template configures the test runner in the PrimeServiceTests.csproj file similar to the following code:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
  <PackageReference Include="xunit" Version="2.2.0" />
  <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>

Für das Testprojekt sind weitere Pakete zum Erstellen und Ausführen von Unittests erforderlich.The test project requires other packages to create and run unit tests. dotnet new hat im vorherigen Schritt xUnit und xUnit Runner hinzugefügt.dotnet new in the previous step added xUnit and the xUnit runner. Fügen Sie jetzt die PrimeService-Klassenbibliothek als eine andere Abhängigkeit zum Projekt hinzu.Now, add the PrimeService class library as another dependency to the project. Verwenden Sie den Befehl dotnet add reference:Use the dotnet add reference command:

dotnet add reference ../PrimeService/PrimeService.csproj

Die ganze Datei finden Sie im Beispielerepository auf GitHub.You can see the entire file in the samples repository on GitHub.

Im Folgenden wird das endgültige Projektmappenlayout gezeigt:The following shows the final solution layout:

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

Um das Testprojekt zur Projektmappe hinzuzufügen, führen Sie den Befehl dotnet sln im Verzeichnis unit-testing-using-dotnet-test aus:To add the test project to the solution, run the dotnet sln command in the unit-testing-using-dotnet-test directory:

dotnet sln add .\PrimeService.Tests\PrimeService.Tests.csproj

Erstellen des ersten TestsCreating the first test

Gemäß dem TDD-Konzept müssen Sie einen fehlerhaften Test schreiben, anschließend dafür sorgen, dass der Test erfolgreich verläuft und dann den Vorgang wiederholen.The TDD approach calls for writing one failing test, making it pass, then repeating the process. Entfernen Sie UnitTest1.cs aus dem PrimeService.Tests-Verzeichnis, und erstellen Sie eine neue C#-Datei namens PrimeService_IsPrimeShould.cs.Remove UnitTest1.cs from the PrimeService.Tests directory and create a new C# file named PrimeService_IsPrimeShould.cs. Fügen Sie den folgenden Code hinzu:Add the following code:

using Xunit;
using Prime.Services;

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

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

        [Fact]
        public void ReturnFalseGivenValueOf1()
        {
            var result = _primeService.IsPrime(1);

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

Das [Fact]-Attribut gibt eine Testmethode an, die von Test Runner ausgeführt wird.The [Fact] attribute indicates a test method that is run by the test runner. Führen Sie im Verzeichnis PrimeService.Tests dotnet test aus, um die Tests und die Klassenbibliothek zu erstellen und anschließend die Tests auszuführen.From the PrimeService.Tests folder, execute dotnet test to build the tests and the class library and then run the tests. Der xUnit Test Runner enthält den Programmeinstiegspunkt zum Ausführen Ihrer Tests.The xUnit test runner contains the program entry point to run your tests. dotnet test startet Test Runner mithilfe des von Ihnen erstellten Komponententestprojekts.dotnet test starts the test runner using the unit test project you've created.

Ihr Test schlägt fehl.Your test fails. Sie haben die Implementierung noch nicht erstellt.You haven't created the implementation yet. Damit dieser Test erfolgreich verläuft, schreiben Sie in der PrimeService-Klasse einen ganz einfachen Code.Make this test by writing the simplest code in the PrimeService class that works. Ersetzen Sie die vorhandene Implementierung der Methode IsPrime durch den folgenden Code:Replace the existing IsPrime method implementation with the following code:

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

Führen Sie dotnet test im PrimeService.Tests-Verzeichnis erneut aus.In the PrimeService.Tests directory, run dotnet test again. Der dotnet test-Befehl führt einen Build für das PrimeService-Projekt und anschließend für das PrimeService.Tests-Projekt aus.The dotnet test command runs a build for the PrimeService project and then for the PrimeService.Tests project. Nachdem beide Projekte erstellt wurden, wird dieser einzelne Test ausgeführt.After building both projects, it runs this single test. Er ist erfolgreich.It passes.

Hinzufügen weiterer FeaturesAdding more features

Nachdem Sie dafür gesorgt haben, dass ein Test erfolgreich verläuft, schreiben Sie weiter.Now that you've made one test pass, it's time to write more. Es gibt einige weitere einfache Fälle für Primzahlen: 0, -1.There are a few other simple cases for prime numbers: 0, -1. Sie könnten diese neuen Fälle als neue Tests mit dem Attribut [Fact] hinzufügen, aber das wird schnell recht mühsam.You could add those cases as new tests with the [Fact] attribute, but that quickly becomes tedious. Es gibt andere xUnit-Attribute, mit deren Hilfe Sie eine Reihe ähnlicher Tests schreiben können:There are other xUnit attributes that enable you to write a suite of similar tests:

  • [Theory] repräsentiert eine Reihe von Tests, die zwar denselben Code ausführen, aber unterschiedliche Eingabeargumente verwenden.[Theory] represents a suite of tests that execute the same code but have different input arguments.

  • Das [InlineData]-Attribut gibt Werte für diese Eingaben an.[InlineData] attribute specifies values for those inputs.

Statt neue Tests zu erstellen, wenden Sie die zwei Attribute [Theory] und [InlineData] zum Erstellen einer einzelnen Theorie in der Datei PrimeService_IsPrimeShould.cs an.Instead of creating new tests, apply these two attributes, [Theory] and [InlineData], to create a single theory in the PrimeService_IsPrimeShould.cs file. Bei der Theorie handelt es sich um eine Methode, die mehrere Werte unter zwei als niedrigste Primzahl testet:The theory is a method that tests several values less than two, which is the lowest prime number:

[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void ReturnFalseGivenValuesLessThan2(int value)
{
    var result = _primeService.IsPrime(value);
    
    Assert.False(result, $"{value} should not be prime");
}

Wenn Sie dotnet test erneut ausführen, sollten bei zwei dieser Tests Fehler auftreten.Run dotnet test again, and two of these tests should fail. Damit alle Tests erfolgreich sind, müssen Sie in der Datei PrimeService.cs am Anfang der Methode IsPrime die if-Klausel ändern:To make all of the tests pass, change the if clause at the beginning of the IsPrime method in the PrimeService.cs file:

if (candidate < 2)

Wiederholen Sie den Vorgang, indem Sie weitere Tests, Theorien und Code in der Hauptbibliothek hinzufügen.Continue to iterate by adding more tests, more theories, and more code in the main library. Sie verfügen über die endgültige Version der Tests und die vollständige Implementierung der Bibliothek.You have the finished version of the tests and the complete implementation of the library.

Zusätzliche RessourcenAdditional resources

Testen von Controllerlogik in ASP.NET CoreTesting controller logic in ASP.NET Core