Exemplarische Vorgehensweise: Testgesteuerte Entwicklung mit dem Test-ExplorerWalkthrough: Test-driven development using Test Explorer

Erstellen Sie Komponententests, damit Ihr Code während inkrementellen Codeänderungen ordnungsgemäß funktioniert.Create unit tests to help keep your code working correctly through incremental code changes. Es gibt mehrere Frameworks, die Sie nutzen können, um Komponententests zu schreiben, darunter auch einige von Drittanbietern.There are several frameworks that you can use to write unit tests, including some developed by third parties. Einige Testframeworks wurden speziell zum Testen in verschiedenen Sprachen oder Plattformen entwickelt.Some test frameworks are specialized for testing in different languages or platforms. Der Test-Explorer stellt eine zentrale Oberfläche für Komponententests in einem dieser Frameworks bereit.Test Explorer provides a single interface for unit tests in any of these frameworks. Weitere Informationen zum Test-Explorers finden Sie unter Ausführen von Komponententests mit dem Test-Explorer und Visual Studio-Test-Explorer – häufig gestellte Fragen.For more information about Test Explorer, see Run unit tests with Test Explorer and Test Explorer FAQ.

In dieser exemplarische Vorgehensweise wird veranschaulicht, wie eine getestete Methode in C# mithilfe des Microsoft-Testframeworks (MSTest) entwickelt wird.This walkthrough demonstrates how to develop a tested method in C# using Microsoft Test Framework (MSTest). Sie können es für andere Sprachen und andere Testframeworks wie NUnit anpassen.You can easily adapt it for other languages or other test frameworks, such as NUnit. Weitere Informationen finden Sie unter Installieren von Frameworks für Komponententests von Drittanbietern.For more information, see Install third-party unit test frameworks.

Erstellen eines Tests und Generieren von CodeCreate a test and generate code

  1. Erstellen Sie ein C#-Projekt für eine Klassenbibliothek (.NET Standard) .Create a C# Class Library (.NET Standard) project. Dieses Projekt enthält den Code, den Sie testen möchten.This project will contain the code that we want to test. Geben Sie dem Projekt den Namen MyMath.Name the project MyMath.

  2. Fügen Sie in derselben Projektmappe ein neues MSTest-Testprojekt (.NET Core) hinzu.In the same solution, add a new MSTest Test Project (.NET Core) project. Geben Sie dem Testprojekt den Namen MathTests.Name the test project MathTests.

    Neue Code- und Testprojekte

  3. Schreiben Sie eine einfache Testmethode, die das Ergebnis überprüft, das für eine bestimmte Eingabe abgerufen wurde.Write a simple test method that verifies the result obtained for a specific input. Fügen Sie der UnitTest1-Klasse folgenden Code hinzu:Add the following code to the UnitTest1 class:

    [TestMethod]
    public void BasicRooterTest()
    {
      // Create an instance to test:
      Rooter rooter = new Rooter();
      // Define a test input and output value:
      double expectedResult = 2.0;
      double input = expectedResult * expectedResult;
      // Run the method under test:
      double actualResult = rooter.SquareRoot(input);
      // Verify the result:
      Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 100);
    }
    
  4. Generieren Sie einen Typ aus dem Testcode.Generate a type from the test code.

    1. Platzieren Sie den Cursor auf Rooter, und wählen Sie dann über das Glühbirnenmenü Typ „Rooter“ generieren > Neuen Typ generieren aus.Place the cursor on Rooter, and then from the light bulb menu, choose Generate type 'Rooter' > Generate new type.

      Schnellaktion: neuen Typ generieren

    2. Legen Sie im Dialogfeld Typ generieren das Projekt auf MyMath (das Klassenbibliotheksprojekt) fest, und klicken Sie auf OK.In the Generate Type dialog box, set Project to MyMath, the class library project, and then choose OK.

      Dialogfeld „Typ generieren“ in Visual Studio 2019

  5. Generieren Sie eine Methode aus dem Testcode.Generate a method from the test code. Platzieren Sie den Cursor auf SquareRoot, und wählen Sie dann über das Glühbirnenmenü Methode „Rooter.SquareRoot“ generieren aus.Place the cursor on SquareRoot, and then from the light bulb menu, choose Generate method 'Rooter.SquareRoot'.

  6. Führen Sie den Komponententest aus.Run the unit test.

    1. Klicken Sie im Menü Test auf Fenster > Test-Explorer, um den Test-Explorer zu öffnen.To open Test Explorer, on the Test menu, choose Windows > Test Explorer.

    2. Klicken Sie im Test-Explorer auf Alle ausführen, um den Test auszuführen.In Test Explorer, choose the Run All button to run the test.

    Die Projektmappe wird erstellt, und der Test wird ausgeführt und schlägt fehl.The solution builds, and the test runs and fails.

  7. Wählen Sie den Namen des Tests aus.Select the name of the test.

    Die Details des Tests werden im Bereich Zusammenfassung der Testdetails angezeigt.The details of the test appear in the Test Detail Summary pane.

    Zusammenfassung der Testdetails im Test-Explorer

  8. Klicken Sie auf den obersten Link unter Stapelüberwachung, um zu der Position zu springen, an der der Test fehlgeschlagen ist.Select the top link under Stack Trace to jump to the location where the test failed.

Sie haben jetzt einen Test und einen Stub erstellt, die Sie ändern können, damit der Test erfolgreich verläuft.At this point, you've created a test and a stub that you can modify so that the test passes.

Überprüfen einer CodeänderungVerify a code change

  1. Verbessern Sie in der Datei Class1.cs den Code von SquareRoot:In the Class1.cs file, improve the code of SquareRoot:

    public double SquareRoot(double input)
    {
        return input / 2;
    }
    
  2. Wählen Sie im Test-Explorer die Option Alle ausführen aus.In Test Explorer, choose Run All.

    Die Projektmappe wird erstellt, und der Test wird erfolgreich ausgeführt.The solution builds, and the test runs and passes.

    Erfolgreicher Test im Test-Explorer

Erweitern des EingabebereichsExtend the range of inputs

Sie können die Wahrscheinlichkeit erhöhen, dass Ihr Code in allen Fällen funktioniert, indem Sie Tests hinzufügen, die einen größeren Bereich an Eingabewerten testen.To improve our confidence that the code works in all cases, add tests that try a broader range of input values.

Tipp

Vermeiden Sie, vorhandene erfolgreiche Tests zu ändern.Avoid altering existing tests that pass. Fügen Sie stattdessen lieber neue Tests hinzu.Instead, add new tests. Ändern Sie vorhandene Tests nur, wenn sich die Benutzeranforderungen ändern.Change existing tests only when the user requirements change. Dieses Vorgehen hilft sicherzustellen, dass durch die Erweiterung des Codes keine vorhandene Funktionalität verloren geht.This policy helps to make sure that you don't lose existing functionality as you work to extend the code.

  1. Fügen Sie in der Testklasse den folgenden Test hinzu, der einen Bereich von Eingabewerten testet:In the test class, add the following test, which tries a range of input values:

    [TestMethod]
    public void RooterValueRange()
    {
        // Create an instance to test.
        Rooter rooter = new Rooter();
    
        // Try a range of values.
        for (double expected = 1e-8; expected < 1e+8; expected *= 3.2)
        {
            RooterOneValue(rooter, expected);
        }
    }
    
    private void RooterOneValue(Rooter rooter, double expectedResult)
    {
        double input = expectedResult * expectedResult;
        double actualResult = rooter.SquareRoot(input);
        Assert.AreEqual(expectedResult, actualResult, delta: expectedResult / 1000);
    }
    
  2. Wählen Sie im Test-Explorer die Option Alle ausführen aus.In Test Explorer, choose Run All.

    Der neue Test schlägt fehl, obwohl der erste Test weiterhin erfolgreich verläuft.The new test fails (although the first test still passes). Sie können die Fehlerquelle ermitteln, indem Sie den fehlgeschlagenen Test auswählen und die Details im Bereich Zusammenfassung der Testdetails anzeigen.To find the point of failure, select the failing test, and then look at the details in the Test Detail Summary pane.

  3. Überprüfen Sie die zu testende Methode, um zu sehen, was falsch sein könnte.Inspect the method under test to see what might be wrong. Ändern Sie den Code von SquareRoot folgendermaßen:Alter the SquareRoot code as follows:

    public double SquareRoot(double input)
    {
      double result = input;
      double previousResult = -input;
      while (Math.Abs(previousResult - result) > result / 1000)
      {
        previousResult = result;
        result = result - (result * result - input) / (2 * result);
      }
      return result;
    }
    
  4. Wählen Sie im Test-Explorer die Option Alle ausführen aus.In Test Explorer, choose Run All.

    Beide Tests sind nun erfolgreich.Both tests now pass.

Hinzufügen von Tests für SonderfälleAdd tests for exceptional cases

  1. Fügen Sie einen neuen Test für negative Eingaben hinzu:Add a new test for negative inputs:

    [TestMethod]
    public void RooterTestNegativeInputx()
    {
        Rooter rooter = new Rooter();
        try
        {
            rooter.SquareRoot(-10);
        }
        catch (System.ArgumentOutOfRangeException)
        {
            return;
        }
        Assert.Fail();
    }
    
  2. Wählen Sie im Test-Explorer die Option Alle ausführen aus.In Test Explorer, choose Run All.

    Die zu testende Methode bildet eine Schleife und muss manuell abgebrochen werden.The method under test loops and must be canceled manually.

  3. Klicken Sie auf der Symbolleiste des Test-Explorers auf Abbrechen.Choose Cancel on the toolbar of Test Explorer.

    Die Ausführung des Tests wird beendet.The test stops executing.

  4. Korrigieren Sie den Code von SquareRoot, indem Sie folgende if-Anweisung am Anfang der Methode hinzufügen:Fix the SquareRoot code by adding the following if statement at the beginning of the method:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
        ...
    
  5. Wählen Sie im Test-Explorer die Option Alle ausführen aus.In Test Explorer, choose Run All.

    Alle Tests sind erfolgreich.All the tests pass.

Umgestalten des zu testenden CodesRefactor the code under test

Führen Sie ein Refactoring für den Code durch, ohne die Tests zu ändern.Refactor the code, but do not change the tests.

Tipp

Ein Refactoring ist eine Änderung, die vorgenommen wird, damit der Code besser funktioniert oder verständlicher wird.A refactoring is a change that is intended to make the code perform better or easier to understand. Eine Umgestaltung sieht nicht vor, das Verhalten des Codes zu ändern. Deshalb werden die Tests nicht geändert.It is not intended to alter the behavior of the code, and therefore the tests are not changed.

Es wird empfohlen, die Schritte der Umgestaltung separat von den Schritten auszuführen, die die Funktionalität erweitern.We recommend that you perform refactoring steps separately from steps that extend functionality. Wenn Sie die Tests nicht ändern, können Sie sichergehen, dass während der Umgestaltung nicht versehentlich Fehler eingebaut wurden.Keeping the tests unchanged gives you confidence that you have not accidentally introduced bugs while refactoring.

  1. Ändern Sie die Zeile, die result in der SquareRoot-Methode berechnet, folgendermaßen:Change the line that calculates result in the SquareRoot method as follows:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
    
        double result = input;
        double previousResult = -input;
        while (Math.Abs(previousResult - result) > result / 1000)
        {
            previousResult = result;
            result = (result + input / result) / 2;
            //was: result = result - (result * result - input) / (2*result);
        }
        return result;
    }
    
  2. Klicken Sie auf Alle ausführen, und überprüfen Sie, ob alle Tests weiterhin erfolgreich ausgeführt werden.Choose Run All, and verify that all the tests still pass.

    Drei erfolgreiche Tests im Test-Explorer