Komponententests für C# mit MSTest und .NET CoreUnit testing C# with MSTest and .NET Core

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 Projektmappendatei für die Klassenbibliothek und das Testprojekt zu erstellen.Inside this new directory, run dotnet new sln to create a new solution file for the class library and the test project. Erstellen Sie als Nächstes ein PrimeService-Verzeichnis.Next, create a PrimeService directory. Die folgende Gliederung zeigt die Verzeichnis- und Dateistruktur:The following outline shows the directory and file structure thus far:

/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.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 eine fehlerhafte Implementierung der PrimeService-Klasse, um eine testgesteuerte Entwicklung (Test Driven Development, TDD) zu verwenden:To use test-driven development (TDD), you 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-mstest.Change the directory back to the unit-testing-using-mstest directory. Führen Sie dotnet sln add PrimeService/PrimeService.csproj aus, um das Klassenbibliotheksprojekt zur Projektmappe hinzuzufügen.Run dotnet sln add PrimeService/PrimeService.csproj to add the class library project to the solution.

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-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.Make the PrimeService.Tests directory the current directory and create a new project using dotnet new mstest. Der neue dotnet-Befehl erstellt ein Testprojekt, das MSTest als Testbibliothek verwendet.The dotnet new command creates a test project that uses MStest as the test library. Die generierte Vorlage konfiguriert das Testprogramm in der Datei PrimeServiceTests.csproj:The generated template configures the test runner in the PrimeServiceTests.csproj file:

<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
  <PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
  <PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
</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 MSTest-SDK, MSTest-Testframework und MSTest-Runner hinzugefügt.dotnet new in the previous step added the MSTest SDK, the MSTest test framework, and the MSTest runner. Fügen Sie jetzt die PrimeService-Klassenbibliothek als weitere 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.

Die folgende Gliederung zeigt das endgültige Projektmappenlayout:The following outline shows the final solution layout:

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

Führen Sie dotnet sln add .\PrimeService.Tests\PrimeService.Tests.csproj im Verzeichnis unit-testing-using-dotnet-test aus.Execute dotnet sln add .\PrimeService.Tests\PrimeService.Tests.csproj in the unit-testing-using-dotnet-test directory.

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 mit folgendem Inhalt:Remove UnitTest1.cs from the PrimeService.Tests directory and create a new C# file named PrimeService_IsPrimeShould.cs with the following content:

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 ReturnFalseGivenValueOf1()
        {
            var result = _primeService.IsPrime(1);

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

Das [TestClass]-Attribut gibt eine Klasse an, die Unittests enthält.The [TestClass] attribute denotes a class that contains unit tests. Das [TestMethod]-Attribut gibt an, dass es sich bei einer Methode um eine Testmethode handelt.The [TestMethod] attribute indicates a method is a test method.

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.Save this file and execute dotnet test to build the tests and the class library and then run the tests. Der MSTest Test Runner verfügt über den Programmeinstiegspunkt zum Ausführen der Tests.The MSTest 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 einen ganz einfachen Code in die PrimeService-Klasse:Make this test pass by writing the simplest code in the PrimeService class that works:

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.In the unit-testing-using-mstest 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 Tests mit dem Attribut [TestMethod] hinzufügen, aber das wird schnell recht mühsam.You could add new tests with the [TestMethod] attribute, but that quickly becomes tedious. Es gibt andere MSTest-Attribute, mit deren Hilfe Sie eine Reihe ähnlicher Tests schreiben können.There are other MSTest attributes that enable you to write a suite of similar tests. Ein [DataTestMethod]-Attribut stellt eine Reihe von Tests dar, die zwar denselben Code ausführen, jedoch unterschiedliche Eingabeargumente verwenden.A [DataTestMethod]attribute represents a suite of tests that execute the same code but have different input arguments. Sie können das Attribut [DataRow] verwenden, um Werte für diese Eingaben anzugeben.You can use the [DataRow] attribute to specify values for those inputs.

Statt neue Tests zu erstellen, wenden Sie diese beiden Attribute zum Erstellen eines einzelnen datengesteuerten Tests an.Instead of creating new tests, apply these two attributes to create a single data driven test. Bei dem datengesteuerten Test handelt es sich um eine Methode, die mehrere Werte unter zwei als niedrigste Primzahl testet:The data driven test is a method that tests several values less than two, which is the lowest prime number: :

[DataTestMethod]
[DataRow(-1)]
[DataRow(0)]
[DataRow(1)]
public void ReturnFalseGivenValuesLessThan2(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.Run dotnet test, and two of these tests fail. Sie müssen die if-Klausel am Anfang der Methode ändern, damit alle Tests erfolgreich sind:To make all of the tests pass, change the if clause at the beginning of the method:

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.

Sie haben eine kleine Bibliothek und eine Reihe von Unittests für diese Bibliothek erstellt.You've built a small library and a set of unit tests for that library. Sie haben die Projektmappe so strukturiert, dass das Hinzufügen neuer Pakete und Tests Teil des normalen Workflows ist.You've structured the solution so that adding new packages and tests is part of the normal workflow. Sie haben den Großteil Ihrer Zeit und Ihres Aufwands mit der Erreichung der Anwendungsziele verbracht.You've concentrated most of your time and effort on solving the goals of the application.