Windows-Apps
Inhaltsverzeichnis reduzieren
Inhaltsverzeichnis erweitern
Markieren Sie das Kontrollkästchen Englisch, um die englische Version dieses Artikels anzuzeigen. Sie können den englischen Text auch in einem Popup-Fenster einblenden, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch
Informationen
Das angeforderte Thema wird unten angezeigt. Es ist jedoch nicht in dieser Bibliothek vorhanden.

Komponententest bei einer Visual C++-DLL für Store-Apps

Visual Studio 2015
 

Veröffentlicht: Juli 2016

Dieses Thema beschreibt eine Möglichkeit zum Erstellen von Komponententests für eine C++-DLL für Windows Store-Apps. Die RooterLib-DLL implementiert eine Funktion zum näherungsweisen Berechnen der Quadratwurzel einer vorgegebenen Zahl, und zwar auf eine Weise, die entfernt an Grenzwertberechnungen in der Analysis erinnert. Die DLL kann dann in eine Windows Store-App eingeschlossen werden, die Benutzern Spaß an der Mathematik vermittelt.

In diesem Thema wird gezeigt, wie Komponententests als erster Schritt in der Entwicklung verwendet werden. Bei dieser Vorgehensweise schreiben Sie zuerst eine Testmethode, die ein bestimmtes Verhalten in Ihrem Testsystem überprüft. Anschließend schreiben Sie den Code, der im Test erfolgreich ist. Durch das Ändern der Reihenfolge bei den folgenden Prozeduren, können Sie diese Strategie umkehren und zuerst den zu testenden Code und anschließend die Komponententests schreiben.

In diesem Thema werden auch eine einzelne Visual Studio-Projektmappe und separate Projekte für die zu testenden Komponententests und DLLs erstellt. Sie können die Komponententests auch direkt in das DLL-Projekt einfügen, oder Sie können separate Lösungen für die Komponententests und die DLL erstellen. Hinweise dazu, welche Struktur verwendet werden soll, erhalten Sie unter Ausführen von Komponententests für vorhandene C++-Anwendungen mit dem Test-Explorer.

  1. Wählen Sie im Menü Datei die Option Neu aus, und klicken Sie dann auf Neues Projekt.

  2. Erweitern Sie im Dialogfeld „Neues Projekt“ den Eintrag Installiert, erweitern Sie Visual C++, und wählen Sie Windows Store aus. Wählen Sie dann Komponententestbibliothek (Windows Store-Apps) aus der Liste der Projektvorlagen aus.

    C++-Komponententestbibliothek Erstellen
  3. Geben Sie dem Projekt den Namen RooterLibTests, legen Sie den Speicherort fest, geben Sie der Projektmappe den Namen RooterLib, und stellen Sie sicher, dass die Option Projektmappenverzeichnis erstellen aktiviert ist.

    Name und Speicherort für Projektmappe und Projekt angeben
  4. Öffnen Sie im neuen Projekt unittest1.cpp.

    unittest1.cpp

    Hinweis:

    • Jeder Test wird definiert, indem TEST_METHOD(YourTestName){...} verwendet wird.

      Sie müssen keine herkömmliche Funktionssignatur schreiben. Die Signatur wird durch das Makro TEST_METHOD erstellt. Das Makro generiert eine Instanzfunktion ohne Rückgabe. Es generiert außerdem eine statische Funktion, die Informationen zur Testmethode zurückgibt. Diese Informationen ermöglichen dem Testexplorer, die Methode zu finden.

    • Testmethoden werden in Klassen gruppiert, indem TEST_CLASS(YourClassName){...} verwendet wird.

      Wenn die Tests ausgeführt werden, wird eine Instanz jeder Testklasse erstellt. Die Testmethoden werden in einer nicht vorgegebenen Reihenfolge aufgerufen. Sie können spezielle Methoden definieren, die vor und nach jedem Modul, Klasse oder Methode aufgerufen werden. Weitere Informationen finden Sie unter Verwenden von Microsoft.VisualStudio.TestTools.CppUnitTestFramework in der MSDN Library.

  1. Fügen Sie den Testcode ein:

    TEST_METHOD(TestMethod1)
    {
        Assert::AreEqual(1,1);
    }
    

    Beachten Sie, dass die Assert-Klasse mehrere statische Methoden zur Verfügung stellt, die Sie verwenden können, um Ergebnisse in den Testmethoden zu überprüfen.

  2. Wählen Sie im Menü Test die Option Ausführen und dann Alle ausführen aus.

    Das Testprojekt wird erstellt und ausgeführt. Das Test-Explorer-Fenster wird angezeigt, und der Test wird unter Bestandene Tests aufgeführt. Unten im Fenster im Bereich "Zusammenfassung" werden weitere Informationen über den ausgewählten Test angezeigt.

    Test-Explorer

  1. Wählen Sie im Projektmappen-Explorer den Projektmappennamen aus. Wählen Sie im Kontextmenü Hinzufügen und dann Neues Projekt hinzufügen aus.

    RooterLib-Projekt erstellen
  2. Wählen Sie im Dialogfeld Neues Projekt hinzufügen die Option DLL (Windows Store-Apps) aus.

  3. Fügen Sie der RooterLib.h-Datei den folgenden Code hinzu:

    // The following ifdef block is the standard way of creating macros which make exporting 
    // from a DLL simpler. All files within this DLL are compiled with the ROOTERLIB_EXPORTS
    // symbol defined on the command line. This symbol should not be defined on any project
    // that uses this DLL. This way any other project whose source files include this file see 
    // ROOTERLIB_API functions as being imported from a DLL, whereas this DLL sees symbols
    // defined with this macro as being exported.
    #ifdef ROOTERLIB_EXPORTS
    #define ROOTERLIB_API  __declspec(dllexport)
    #else
    #define ROOTERLIB_API __declspec(dllimport)
    #endif //ROOTERLIB_EXPORTS
    
    class ROOTERLIB_API CRooterLib {
    public:
        CRooterLib(void);
        double SquareRoot(double v);
    };
    

    Die Kommentare enthalten nicht nur für den Entwickler der DLL, sondern auch für alle Anwender, die in ihrem Projekt auf die DLL verweisen, Erläuterungen zum ifdef-Block. Sie können das ROOTERLIB_EXPORTS-Symbol in der Befehlszeile mithilfe der Projekteigenschaften der DLL hinzufügen.

    Die CRooterLib-Klasse deklariert einen Konstruktor und die SqareRoot-Abschätzermethode.

  4. Fügen Sie der Befehlszeile das ROOTERLIB_EXPORTS-Symbol hinzu.

    1. Wählen Sie im Projektmappen-Explorer das Projekt RooterLib aus, und klicken Sie anschließend im Kontextmenü auf Eigenschaften.

      Präprozessorsymboldefinition hinzufügen
    2. Erweitern Sie im Dialogfeld „Eigenschaftenseite“ für RooterLib die Option Konfigurationseigenschaften und dann C++, und wählen Sie Präprozessor.

    3. Wählen Sie <Bearbeiten...> in der Liste Präprozessordefinitionen aus, und fügen Sie dann dem Dialogfeld „Präprozessordefinitionen“ ROOTERLIB_EXPORTS hinzu.

  5. Fügen Sie minimale Implementierungen der deklarierten Funktionen hinzu. Öffnen Sie RooterLib.cpp, und fügen Sie den folgenden Code hinzu:

    // constructor
    CRooterLib::CRooterLib()
    {
    }
    
    // Find the square root of a number.
    double CRooterLib::SquareRoot(double v)
    {
        return 0.0;
    }
    
    
    

  1. Fügen Sie dem Projekt "RooterLibTests" "RooterLib" hinzu.

    1. Wählen Sie im Projektmappen-Explorer das Projekt RooterLibTests aus, und wählen Sie dann im Kontextmenü die Option Verweise aus.

    2. Erweitern Sie im Dialogfeld „Projekteigenschaften“ von RooterLib die Option Allgemeine Eigenschaften, und wählen Sie Framework und Verweise.

    3. Wählen Sie Neuen Verweis hinzufügen aus.

    4. Erweitern Sie im Dialogfeld Verweis hinzufügen den Eintrag Projektmappe, und wählen Sie Projekte aus. Wählen Sie dann das Element RouterLib aus.

  2. Fügen Sie die RooterLib-Headerdatei in unittest1.cpp ein.

    1. Öffnen Sie unittest1.cpp.

    2. Fügen Sie diesen Code unter der Zeile #include "CppUnitTest.h" hinzu:

      #include "..\RooterLib\RooterLib.h"
      
  3. Fügen Sie einen Test hinzu, der die importierte Funktion verwendet. Fügen Sie den folgenden Code zu unittest1.cpp hinzu:

    TEST_METHOD(BasicTest)
    {
        CRooterLib rooter;
        Assert::AreEqual(
            // Expected value:
            0.0, 
            // Actual value:
            rooter.SquareRoot(0.0), 
            // Tolerance:
            0.01,
            // Message:
            L"Basic test failed",
            // Line number - used if there is no PDB file:
            LINE_INFO());
    }
    
    
    
  4. Erstellen Sie die Projektmappe.

    Der neue Test wird im Test-Explorer im Knoten Nicht ausgeführte Tests angezeigt.

  5. Wählen Sie im Test-Explorer Alle ausführen aus.

    Einfacher Test bestanden

Sie haben den Test und die Codeprojekte eingerichtet und überprüft, dass Sie Tests ausführen können, die Funktionen im Codeprojekt ausführen. Jetzt können Sie beginnen, echte Tests und Code zu schreiben.

  1. Fügen Sie einen neuen Test hinzu:

    TEST_METHOD(RangeTest)
    {
        CRooterLib rooter;
        for (double v = 1e-6; v < 1e6; v = v * 3.2)
        {
            double expected = v;
            double actual = rooter.SquareRoot(v*v);
            double tolerance = expected/1000;
            Assert::AreEqual(expected, actual, tolerance);
        }
    };
    
    
    System_CAPS_tipTipp

    Es wird empfohlen, keine Tests zu ändern, die erfolgreich waren. Stattdessen fügen Sie einen neuen Test hinzu, aktualisieren den Code, sodass der Test erfolgreich ist, und dann fügen Sie einen weiteren Test hinzu, usw.

    Wenn Benutzer ihre Anforderungen ändern, deaktivieren Sie die Tests, die nicht mehr richtig sind. Schreiben Sie neue Tests und aktivieren Sie sie, einen nach dem anderen, in derselben inkrementellen Art.

  2. Wählen Sie im Test-Explorer Alle ausführen aus.

  3. Der Test schlägt fehl.

    Fehler beim RangeTest
    System_CAPS_tipTipp

    Stellen Sie bei jedem Test unmittelbar nachdem Sie ihn geschrieben haben sicher, dass ein Fehler bei seiner Ausführung auftritt. Dies hilft Ihnen, den einfachen Fehler zu vermeiden, einen Test zu schreiben, der niemals fehlschlägt.

  4. Erweitern Sie den Code unter dem Test, damit der neue Test erfolgreich ist. Fügen Sie RooterLib.cpp Folgendes hinzu:

    #include <math.h>
    ...
    // Find the square root of a number.
    double CRooterLib::SquareRoot(double v)
    {
        double result = v;
        double diff = v;
        while (diff > result/1000)
        {
            double oldResult = result;
            result = result - (result*result - v)/(2*result);
            diff = abs (oldResult - result);
        }
        return result;
    }
    
    
  5. Erstellen Sie die Projektmappe und wählen Sie dann im Test-Explorer, Alle ausführen aus.

    Beide Tests sind erfolgreich.

System_CAPS_tipTipp

Entwickeln Sie Code, indem Sie währenddessen Tests hinzufügen. Stellen Sie sicher, dass alle Tests nach jeder Iteration erfolgreich sind.

  1. Fügen Sie einen anderen Test zu unittest1.cpp hinzu:

    // Verify that negative inputs throw an exception.
     TEST_METHOD(NegativeRangeTest)
     {
       wchar_t message[200];
       CRooterLib rooter;
       for (double v = -0.1; v > -3.0; v = v - 0.5)
       {
         try 
         {
           // Should raise an exception:
           double result = rooter.SquareRoot(v);
    
           swprintf_s(message, L"No exception for input %g", v);
           Assert::Fail(message, LINE_INFO());
         }
         catch (std::out_of_range ex)
         {
           continue; // Correct exception.
         }
         catch (...)
         {
           swprintf_s(message, L"Incorrect exception for %g", v);
           Assert::Fail(message, LINE_INFO());
         }
       }
    };
    
    
  2. Wählen Sie im Test-Explorer Alle ausführen aus.

    Der Test schlägt fehl. Wählen Sie den Testnamen im Test-Explorer aus. Die Assertation, bei der ein Fehler aufgetreten ist, wird gekennzeichnet. Die Fehlermeldung wird im Detailbereich vom Test-Explorer angezeigt.

    Fehler bei NegativeRangeTests
  3. Um zu finden, warum der Test fehlschlägt, debuggen Sie schrittweise durch die Funktion:

    1. Legen Sie einen Haltepunkt am Anfang der SquareRoot-Funktion fest.

    2. Wählen Sie im Kontextmenü des fehlgeschlagenen Tests die Option Ausgewählte Tests debuggen aus.

      Wenn die Ausführung am Haltepunkt stoppt, durchlaufen Sie den Code schrittweise.

    3. Fügen Sie RooterLib.cpp Code hinzu, um die Ausnahme abzufangen:

      #include <stdexcept>
      ...
      double CRooterLib::SquareRoot(double v)
      {
          //Validate the input parameter:
          if (v < 0.0) 
          {
            throw std::out_of_range("Can't do square roots of negatives");
          }
      ...
      
      
    1. Wählen Sie im Test-Explorer Alle ausführen aus, um die korrigierte Methode zu testen und zu überprüfen, dass Sie keine Regression eingeführt haben.

Alle Tests sind nun erfolgreich.

Alle Tests erfolgreich

  1. Vereinfachen Sie die zentrale Berechnung in der SquareRoot-Funktion:

    // old code
    //result = result - (result*result - v)/(2*result);
    // new code
    result = (result + v/result) / 2.0;
    
    
  2. Wählen Sie Alle ausführen aus, um die umgestaltete Methode zu testen und zu überprüfen, dass Sie keine Regression eingeführt haben.

    System_CAPS_tipTipp

    Mit einem stabilen Satz guter Komponententests haben Sie mehr Gewissheit, dass Sie beim Ändern des Codes keine Fehler eingeführt haben.

    Halten Sie Umgestaltungen getrennt von anderen Änderungen.

Anzeigen:
© 2016 Microsoft