Freigeben über


Exemplarische Vorgehensweise: Testgesteuerte Entwicklung mithilfe des Test-Explorers

Erstellen Sie Unit-Tests, um sicherzustellen, dass Ihr Code durch inkrementelle Codeänderungen korrekt funktioniert. Es gibt mehrere Frameworks, mit denen Sie Komponententests schreiben können, einschließlich einiger von Drittanbietern entwickelter Komponenten. Einige Testframeworks sind auf Tests in verschiedenen Sprachen oder Plattformen spezialisiert. Der Test-Explorer stellt eine einzelne Schnittstelle für Komponententests in einem dieser Frameworks bereit. Weitere Informationen zum Test-Explorer finden Sie unter Ausführen von Komponententests mit Test-Explorer und 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 exemplarischen Vorgehensweise wird die Entwicklung einer getesteten Methode in C# mithilfe von Microsoft Test Framework (MSTest) veranschaulicht. Sie können sie ganz einfach für andere Sprachen oder andere Testframeworks anpassen, z. B. NUnit. Weitere Informationen finden Sie unter Installieren von Komponententestframeworks von Drittanbietern.

Erstellen eines Tests und Generieren von Code

  1. Erstellen Sie ein C# -Klassenbibliotheksprojekt für .NET oder .NET Standard. Dieses Projekt enthält den Code, den wir testen möchten. Benennen Sie das Projekt "MyMath".

  2. Fügen Sie in derselben Lösung ein neues MSTest-Testprojekt für .NET hinzu.

    In Visual Studio 2019, Version 16.9, ist der Name der MSTest-Projektvorlage Unit Test Project.

    Nennen Sie das Testprojekt MathTests.

    Neuer Code und Testprojekte

    Neuer Code und Testprojekte

  3. Schreiben Sie im Testprojekt eine einfache Testmethode, mit der das ergebnis überprüft wird, das für eine bestimmte Eingabe abgerufen wurde. Fügen Sie den folgenden Code zur Klasse Test1 oder UnitTest1 hinzu.

    [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.

    1. Platzieren Sie den Cursor auf Rooter, und öffnen Sie dann das Glühbirnenmenü.

      Wählen Sie "Neuen Typ generieren" aus.

      Schnelle Aktion zum Generieren eines neuen Typs

      Wählen Sie "Rooter" generieren> und neuen Typ generieren.

      Schnelle Aktion zum Generieren eines neuen Typs

    2. Legen Sie im Dialogfeld "Typ generieren" das Projekt auf "MyMath", das Klassenbibliotheksprojekt, und wählen Sie dann "OK" aus.

      Dialogfeld

      Dialogfeld

  5. Generieren Sie eine Methode aus dem Testcode. Platzieren Sie den Cursor auf SquareRoot, und wählen Sie dann im Glühbirnenmenü die Methode 'Methode "SquareRoot" generieren' oder 'Methode "Rooter.SquareRoot" generieren' aus.

  6. Führen Sie den Komponententest aus.

    1. Öffnen Sie den Test-Explorer.

      Um den Test-Explorer über das Menü " Test " zu öffnen, wählen Sie "Test-Explorer" aus.

      Um den Test-Explorer über das Menü " Test " zu öffnen, wählen Sie den Windows>Test-Explorer aus.

    2. Wählen Sie im Test-Explorer die Schaltfläche "Alle ausführen " aus, um den Test auszuführen.

    Die Lösung wird erstellt, und der Test wird ausgeführt und schlägt fehl.

  7. Wählen Sie den Namen des Tests aus.

    Die Details des Tests werden im Bereich " Zusammenfassung der Testdetails " angezeigt.

    Testdetailszusammenfassung im Test-Explorer

    Testdetailszusammenfassung im Test-Explorer

  8. Wählen Sie den oberen Link unter Stack Trace aus, um zu dem Speicherort zu springen, an dem der Test fehlgeschlagen ist.

An diesem Punkt haben Sie einen Test und einen Stub erstellt, den Sie so ändern können, dass der Test bestanden wird.

Überprüfen einer Codeänderung

  1. Verbessern Sie in der datei Class1.cs den Code von SquareRoot:

    public double SquareRoot(double input)
    {
        return input / 2;
    }
    
  2. Wählen Sie im Test-Explorer"Alle ausführen" aus.

    Die Lösung wird erstellt, und der Test wird ausgeführt und bestanden.

    Test-Explorer mit bestandenem Test

    Test-Explorer mit bestandenem Test

Erweitern des Eingabebereichs

Um unser Vertrauen zu verbessern, dass der Code in allen Fällen funktioniert, fügen Sie Tests hinzu, die einen breiteren Bereich von Eingabewerten ausprobieren.

Tipp

Vermeiden Sie das Ändern von Tests, die bereits bestanden haben. Fügen Sie stattdessen neue Tests hinzu. Ändern Sie vorhandene Tests nur, wenn sich die Benutzeranforderungen ändern. Mit dieser Richtlinie können Sie sicherstellen, dass beim Erweitern des Codes keine vorhandenen Funktionen verloren gehen.

  1. Fügen Sie in der Testklasse den folgenden Test hinzu, der einen Bereich von Eingabewerten versucht:

    [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"Alle ausführen" aus.

    Der neue Test schlägt fehl (obwohl der erste Test noch bestanden ist). Um den Fehlerpunkt zu finden, wählen Sie den Fehlerhaften Test aus, und sehen Sie sich dann die Details im Bereich " Testdetailzusammenfassung " an.

  3. Überprüfen Sie die Methode im Test, um festzustellen, was falsch sein könnte. Ändern Sie den SquareRoot Code wie folgt:

    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"Alle ausführen" aus.

    Beide Tests bestehen jetzt.

Hinzufügen von Tests für Ausnahmefälle

  1. Fügen Sie einen neuen Test für negative Eingaben hinzu:

    [TestMethod]
    public void RooterTestNegativeInput()
    {
        Rooter rooter = new Rooter();
        Assert.ThrowsException<ArgumentOutOfRangeException>(() => rooter.SquareRoot(-1));
    }
    
  2. Wählen Sie im Test-Explorer"Alle ausführen" aus.

    Der neue Test schlägt fehl.

    Wenn die getestete Methode in eine Schleife gerät, wählen Sie Abbrechen auf der Symbolleiste des Test-Explorers aus. Der Test beendet die Ausführung und schlägt fehl.

  3. Korrigieren Sie den SquareRoot Code, indem Sie die folgende if Anweisung am Anfang der Methode hinzufügen:

    public double SquareRoot(double input)
    {
        if (input <= 0.0)
        {
            throw new ArgumentOutOfRangeException();
        }
        ...
    
  4. Wählen Sie im Test-Explorer"Alle ausführen" aus.

    Alle Tests bestehen.

Refaktorisiere den zu testenden Code

Umgestalten Sie den Code, ändern Sie die Tests jedoch nicht.

Tipp

Ein Refactoring ist eine Änderung, die dazu gedacht ist, den Code leistungsfähiger zu machen und ihn leichter verständlich zu gestalten. Es ist nicht vorgesehen, das Verhalten des Codes zu ändern, und daher werden die Tests nicht geändert.

Es wird empfohlen, die Umgestaltungsschritte getrennt von den Schritten auszuführen, die die Funktionalität erweitern. Wenn Sie die Tests unverändert beibehalten, können Sie sicher sein, dass Sie beim Umgestalten nicht versehentlich Fehler eingeführt haben.

  1. Ändern Sie die Zeile, die result in der SquareRoot-Methode wie folgt berechnet:

    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. Wählen Sie "Alle ausführen" aus, und stellen Sie sicher, dass alle Tests noch bestehen.

    Test-Explorer mit 3 bestandenen Tests

    Test-Explorer mit 3 bestandenen Tests