VERTRIEB: 1-800-867-1380

Anleitungen zum effizienten Testen von Azure-Lösungen

Letzte Aktualisierung: Juni 2014

Autor: Suren Machiraju

Bearbeiter: Jaime Alva Bravo und Steve Wilkins

Nachdem Sie Ihre Microsoft Azure-Lösung entworfen, programmiert und bereitgestellt haben, müssen Sie manchmal feststellen, dass sie nicht funktioniert. In diesem Artikel erhalten Sie Hilfestellungen zum Testen Ihrer Microsoft Azure-Anwendungen während des Softwareentwicklungs-Lebenszyklus. Der Testumfang beinhaltet die Geschäftslogik sowie umfassende End-to-End-Szenariotests. Dieser Artikel zeigt exemplarische Vorgehensweisen für Folgendes:

  • Entwickeln von Komponententests für die Geschäftslogikkomponenten bei gleichzeitiger Beseitigung on Abhängigkeiten von Microsoft Azure-Komponenten.

  • Entwerfen von End-to-End-Integrationstests.

  • Beseitigen von Mehraufwand bei Setup, Initialisierung, Bereinigung und Löschen der Microsoft Azure Service-Ressourcen (z. B. Warteschlangen) bei jedem Testlauf.

  • Beseitigen der Erstellung doppelter Infrastrukturen für ACS-Namespaces, Service Bus-Warteschlangen und andere Ressourcen.

Zusätzlich bietet dieser Artikel einen Überblick der verschiedenen Testtechnologien und -methoden zum Testen Ihrer Microsoft Azure-Anwendungen.

Die folgenden Änderungen sind in diesem Artikel neu:

  1. Wir verwenden Visual Studio 2013.

  2. Microsoft Fakes in Visual Studio 2013 ersetzt Moles. Wir beschreiben dieses Feature in dem Artikel „Isolieren von getestetem Code mithilfe von Microsoft Fakes“.

  3. In Visual Studio 2013 ist jetzt eine neue Version von Codeabdeckung verfügbar, die direkt aus dem Test-Explorer aufgerufen wird. Eine Beschreibung finden Sie in dem Artikel „Bestimmen des Umfangs des zu testenden Codes mithilfe von Codeabdeckung“.

  4. Das Pex-Team hat jetzt eine Lightweight-Version von Pex namens Code Digger veröffentlicht. Eine Beschreibung finden Sie in dem Artikel „Microsoft Code Digger“.

  5. Beginnend mit Visual Studio 2012 empfehlen wir nicht mehr das Testen privater Methoden. Eine Erklärung finden Sie unter „My Take on Unit Testing Private Methods“.

Es gibt zwei Arten von Tests:

  • Komponententests sind eng fokussierte Tests, die eine einzige, spezifische Funktion ausführen. Wir bezeichnen diese Tests als „Getesteten Code“ (CUT, Code Unter Test). Sie müssen alle Abhängigkeiten entfernen, die der CUT erfordert.

  • Integrationstests sind breiter angelegte Tests, die mehrere Teile einer Funktionalität gleichzeitig ausführen. In vielen Fällen ähnelt dies einem Komponententest, doch Integrationstests decken mehrere Featurebereiche ab und umfassen mehrere Abhängigkeiten.

Insgesamt konzentrieren sich diese Tests auf das Erstellen und Verwenden von Test-Doubles. Wir verwenden folgende Typen von Test-Doubles:

  • Fakes sind simulierte Objekte, die dieselbe Schnittstelle implementieren wie das von ihnen dargestellte Objekt. Fakes geben vordefinierte Antworten zurück. Ein Fake enthält einen Satz von Methodenstubs und dient als Ersatz für die von Ihnen programmgesteuert erstellten Objekte.

  • Stubs simulieren das Verhalten von Softwareobjekten.

  • Shims ermöglichen es Ihnen, Ihren Code von Assemblys zu isolieren, die nicht Bestandteil Ihrer Projektmappe sind. Sie isolieren außerdem Komponenten Ihrer Projektmappe voneinander.

Sobald sie einmal ausgeführt werden, können diese Tests den Zustand und das Verhalten überprüfen. Beispielsweise umfasst der Zustand das Ergebnis nach dem Aufrufen einer Methode und der Rückgabe eines bestimmten Werts. Ein Beispiel für Verhalten ist das Aufrufen einer Methode in einer bestimmten Reihenfolge oder in einer bestimmten Anzahl.

Eins der Hauptziele von Komponententests ist es, Abhängigkeiten zu beseitigen. Beim Azure-Framework umfassen diese Abhängigkeiten Folgendes:

  • Service Bus-Warteschlangen

  • Zugriffssteuerungsdienst

  • Cache

  • Azure-Tabellen-, BLOBs und Warteschlangen

  • Azure SQL-Datenbank

  • Azure Drive (früher Cloud-Laufwerk)

  • Andere Webdienste

Beim Erstellen von Tests für Azure-Anwendungen werden diese Abhängigkeiten ersetzt, um die Tests auf das Ausführen der Logik zu konzentrieren.

Die Beispiele zu Service Bus-Warteschlangen (einschließlich Tools und Methoden), die wir in diesem Artikel besprechen, gelten auch für alle anderen Abhängigkeiten.

Um das Testframework für Ihre Microsoft Azure-Anwendungen zu implementieren, benötigen Sie Folgendes:

  • Ein Komponententest-Framework zum Definieren und Ausführen Ihrer Tests

  • Ein Pseudoframework, das Ihnen hilft, Abhängigkeiten zu isolieren und eng umgrenzte Komponententests zu erstellen.

  • Tools, die bei der automatischen Generierung von Komponententests helfen, um die Codeabdeckung zu erhöhen.

  • Andere Frameworks, die bei testbaren Entwürfen hilfreich sein können, indem sie die Abhängigkeiteneinschleusung ausnutzen und das Steuerungsumkehrmuster (Inversion of Control Pattern, IoC) anwenden.

Visual Studio enthält ein Befehlszeilen-Hilfsprogramm namens MS Test zum Ausführen von in Visual Studio erstellten Komponententests. Visual Studio enthält außerdem eine Suite von Projekt- und Elementvorlagen zur Unterstützung von Tests. Normalerweise erstellen Sie ein Testprojekt und fügen dann Klassen hinzu (bekannt als Testvorrichtungen), die durch das Attribut [TestClass] gekennzeichnet sind. Die Klassen enthalten Methoden, die mit dem Attribut [TestMethod] gekennzeichnet sind. In MS Test gestatten Ihnen verschiedene Fenster innerhalb von Visual Studio das Ausführen von im Projekt definierten Komponententests. Sie können die Ergebnisse auch nach der Ausführung überprüfen.

noteHinweis
Die Editionen Visual Studio 2013 Express, Professional und Test Professional enthalten MS Test nicht.

In MS Test befolgen Komponententests ein AAA-Muster: Anordnen, Agieren und Assertion.

  • Anordnen – Erstellen jeglicher vorausgesetzter Objekte, Konfigurationen und aller anderen notwendigen Voraussetzungen und Eingaben die der CUT benötigt.

  • Agieren – Ausführen des tatsächlichen, eng umgrenzten Tests mit dem Code.

  • Assertion – Überprüfen, dass die erwarteten Ergebnisse herausgekommen sind.

Die Bibliotheken des MS Test-Frameworks enthalten die Hilfsklassen PrivateObject und PrivateType. Diese Klassen verwenden Reflektion, um das Aufrufen nicht öffentlicher Instanzmember oder statischer Member aus dem Komponententestcode heraus zu erleichtern.

Die Premium- und Ultimate-Editionen von Visual Studio umfassen erweiterte Komponententesttools. Diese Tools integrieren sich in MS Test. Die Tools ermöglichen Ihnen außerdem, die Menge des Codes zu analysieren, der von Ihren Komponententests ausgeführt wird. Zusätzlich führen die Tools eine Farbcodierung des Quellcodes durch, um die Abdeckung anzuzeigen. Das Feature nennt sich Codeabdeckung.

Ein Ziel von Komponententests ist es, Code isoliert zu testen. Häufig können Sie den CUT aber nicht isoliert testen. Manchmal ist der Code nicht unter dem Aspekt der Testbarkeit geschrieben. Den Code umzuschreiben, wäre schwierig, weil er von anderen Bibliotheken abhängig ist, die sich nicht einfach isolieren lassen. Beispielsweise lässt sich Code, der mit externen Umgebungen interagiert, nicht einfach isolieren. Ein Pseudoframework hilft Ihnen dabei, beide Typen von Abhängigkeiten zu isolieren.

Eine Liste von Pseudoframeworks, die Sie in Erwägung ziehen sollten, finden Sie im Abschnitt mit den Links am Ende dieses Artikels. Dieser Artikel konzentriert sich auf die Verwendung von Microsoft Fakes.

Microsoft Fakes hilft Ihnen bei der Isolierung des zu testenden Codes, indem andere Teile der Anwendung durch Stubs oder Shims ersetzt werden. Hierbei handelt es sich um kleine Codestücke, die von Ihren Tests kontrolliert werden. Indem Sie den Code für die Tests isolieren, wissen Sie beim Fehlschlagen des Tests, dass die Ursache im isolierten Code und nicht an anderer Stelle liegt. Stubs und Shims ermöglichen es Ihnen außerdem, Ihren Code sogar dann zu testen, wenn andere Teile Ihrer Anwendung noch nicht funktionieren.

Es gibt zwei Arten von Fakes:

  • Ein Stub tauscht eine Klasse gegen einen kleinen Ersatz aus, der dieselbe Schnittstelle implementiert. Um Stubs zu verwenden, müssen Sie Ihre Anwendung so entwerfen, dass jede Komponente nur von Schnittstellen und nicht von anderen Komponenten abhängig ist. Mit „Komponente“ ist eine Klasse oder Gruppe von Klassen gemeint, die gemeinsam entworfen und aktualisiert werden und normalerweise in einer Assembly enthalten sind.

  • Ein Shim ändert den kompilierten Code Ihrer Anwendung zur Laufzeit. Statt einen bestimmten Methodenaufruf auszuführen, führt Ihre Anwendung den Shimcode aus, den Ihr Test zur Verfügung stellt. Mit Shims können Sie Aufrufe von Assemblys ersetzen, die Sie nicht ändern können, beispielsweise .NET-Assemblys.

Code Digger analysiert mögliche Ausführungspfade durch Ihren .NET-Code. Das Ergebnis ist eine Tabelle, in der in jeder Zeile ein eindeutiges Verhalten Ihres Codes angezeigt wird. Die Tabelle hilft Ihnen dabei, das Verhalten Ihres Codes zu verstehen, und kann versteckte Fehler aufdecken.

Um Ihren Code im Visual Studio-Editor zu analysieren, verwenden Sie das neue Kontextmenüelement Generate Inputs/Outputs Table, um Code Digger aufzurufen. Code Digger berechnet Eingabe/Ausgabe-Paare und zeigt diese an. Code Digger sucht systematisch nach Fehlern, Ausnahmen und Assertionsfehlern.

Standardmäßig verarbeitet Code Digger nur öffentlichen .NET-Code, der sich in portablen Klassenbibliotheken befindet. Später in diesem Artikel werden wir noch besprechen, wie Sie Code Digger konfigurieren müssen, um andere .NET-Projekte zu untersuchen.

Code Digger verwendet das Pex-Modul und die Z3-Einschränkungsauflösung von Microsoft Research, um alle Verzweigungen im Code systematisch zu analysieren. Code Digger versucht, eine Testsuite zu generieren, die eine hohe Codeabdeckung erzielt.

Sie können Microsoft Unity für die erweiterbare Abhängigkeiteneinschleusung (Dependency Injection, DI) und für Steuerungsumkehrcontainer (Inversion of Control, IoC) verwenden. Es unterstützt Abfangen, Konstruktoreinschleusung, Eigenschafteneinschleusung und Methodenaufrufeinschleusung. Microsoft Unity und ähnliche Tools helfen Ihnen beim Erstellen testbarer Entwürfe, in die Sie Ihre Abhängigkeiten auf allen Ebenen der Anwendung einschleusen können. (Wir gehen davon aus, dass Ihre Anwendung unter Berücksichtigung der Abhängigkeiteneinschleusung und eines dieser Frameworks entworfen und erstellt wurde.)

Diese Frameworks eignen sich sehr gut zum Schreiben von testbarem Code und somit letztendlich von „gutem“ Code. Sie können bei den ersten Entwurfsanforderungen jedoch relativ anspruchsvoll sein. In diesem Artikel werden Abhängigkeiteneinschleusung (DI) und Steuerungsumkehrcontainer (IoC) nicht behandelt.

In diesem Abschnitt wird eine Lösung beschrieben, die eine auf einer Webrolle gehostete Website enthält. Die Website sendet Nachrichten per Push an eine Warteschlange. Dann werden Nachrichten aus der Warteschlange von einer Workerrolle verarbeitet. Wir möchten Aspekte von allen drei Komponenten testen.

Stellen Sie sich vor, dass Sie eine Website haben, die Bestellungen erstellt, sowie eine Service Bus-Warteschlange, die eine Warteschlange zur Verarbeitung dieser Bestellungen erstellt. Die Webseite sieht ungefähr wie in Abbildung 1 aus:

Abbildung 1

Wenn der Benutzer auf Erstellen klickt, stellt die Service Bus-Warteschlange die neue Bestellung der „Create“-Aktion im zugeordneten Controller bereit. Die Aktion ist wie folgt implementiert:

noteHinweis
Die „MicrosoftAzureQueue“-Klasse ist eine Wrapperklasse, die die .NET APIs des Service Bus verwendet (z. B: „MessageSender“ und „MessageReceiver“), um mit den Service Bus-Warteschlangen zu interagieren.

private IMicrosoftAzureQueue queue;
public OrderController()
{
    queue = new MicrosoftAzureQueue();
}
public OrderController(IMicrosoftAzureQueue queue)
{
    this.queue = queue;
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderId,Description")] Order order)
{
    try
    {
        if (ModelState.IsValid)
        {
            string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            string queueName = "ProcessingQueue";
            queue.InitializeFromConnectionString(connectionString, queueName);
            queue.Send(order);
        }
        return View("OrderCreated");
    }
    catch (Exception ex)
    {
        Trace.TraceError(ex.Message);
        return View("Error");
    }            
}

Beachten Sie, dass der Code Konfigurationseinstellungen aus CloudConfigurationManager abruft und eine Nachricht, die die Bestellung enthält, an die Warteschlange sendet. Beachten Sie ferner, dass die Create-Aktion die folgenden Methoden verwendet:

  • InitializeFromConnectionString (ConnectionString-Zeichenfolge, QueueName-Zeichenfolge)

  • Send (MicrosoftAzureQueue-Klasse)

Wir möchten für diese Methoden Umleitungen erstellen, indem wir ihr Verhalten mithilfe von Fakes kontrollieren und die Abhängigkeiten von der echten Umgebung entfernen. Die Verwendung von Fakes beseitigt die Notwendigkeit, die Tests im Azure-Emulator auszuführen oder die Service Bus-Warteschlange aufzurufen. Wir führen die „Create“-Aktion auf dem Controller aus, um zu überprüfen, ob die Bestellungseingabe die an die Warteschlange gesendete ist. Die Send-Methode überprüft, ob die Eingabe die Bestellungs-ID und Beschreibung enthält, wie sie an die Aktion übergeben wurden. Danach prüft sie, ob als Ergebnis die Ansicht „OrderCreated“ angezeigt wird.

Ein Komponententest lässt sich für die voranstehende Implementierung mithilfe von Fakes einfach erstellen. Klicken Sie in dem Testprojekt mit der rechten Maustaste auf die Assembly, die die Typen enthält, die Sie modellieren möchten. Wählen Sie dann Fakes-Assembly hinzufügen aus.

In dem Beispiel wählen wir zuerst Microsoft.ServiceBus und dann Fakes-Assembly hinzufügen aus. Dem Testprojekt wird eine XML-Datei namens „Microsoft.ServiceBus.Fakes“ hinzugefügt. Wiederholen Sie die Aktion für die „Microsoft.WindowsAzure.Configuration“-Assembly.

Wenn Sie das Testprojekt erstellen, werden den automatisch generierten Pseudoversionen dieser Assemblys Verweise hinzugefügt. In dem Beispiel sind die generierten Assemblys „Microsoft.ServiceBus.Fakes“ und „Microsoft.WindowsAzure.Configuration“.

Erstellen Sie eine Komponententestmethode, und wenden Sie das Attribut [TestCategory("With Fakes")] an. Innerhalb des Komponententests verwenden Sie Shims, um Teile Ihrer Anwendung voneinander zu isolieren.

Verwenden von Shims, um Ihre Anwendung für Komponententests von anderen Assemblys zu isolieren

Shims sind eine von zwei Technologien, die vom Microsoft Fakes-Framework bereitgestellt werden, mit deren Hilfe Sie getestete Komponenten einfach von der Umgebung isolieren können. Shims leiten Aufrufe bestimmter Methoden an Code um, den Sie als Teil Ihres Tests schreiben. Viele Methoden geben in Abhängigkeit von den externen Bedingungen unterschiedliche Ergebnisse zurück. Ein Shim wird jedoch von Ihrem Test kontrolliert und kann bei jedem Aufruf konsistente Ergebnisse zurückgeben. Die erleichtert das Schreiben Ihrer Tests ungemein. Verwenden Sie Shims, um Ihren Code von Assemblys zu isolieren, die nicht Bestandteil Ihrer Projektmappe sind. Um Komponenten Ihrer Projektmappe voneinander zu isolieren, empfehlen wir die Verwendung von Stubs.

Verwenden von Shims, um Teile Ihrer Anwendung für Komponententests voneinander zu isolieren

Stubs sind eine von zwei Technologien, die vom Microsoft Fakes-Framework bereitgestellt werden, mit deren Hilfe Sie eine getestete Komponente von anderen, von ihr aufgerufenen Komponenten isolieren können. Ein Stub ist ein kleines Codestück, das während des Tests den Platz einer anderen Komponente einnimmt. Der Vorteil bei der Verwendung eines Stubs besteht darin, dass er konsistente Ergebnisse zurückgibt, weshalb sich der Test einfacher schreiben lässt. Außerdem können Sie Tests sogar dann ausführen, wenn die anderen Komponenten noch nicht funktionieren.

In unserem Testfall verwenden wir Shims für die Azure-Assemblys „CloudConfigurationManager“ und „BrokeredMessage“. Wir verwenden Stubs für „MicrosoftAzureQueue“, wobei es sich um eine Klasse in unserer Projektmappe handelt.

[TestMethod]
[TestCategory("With fakes")]
public void Test_Home_CreateOrder()
{
    // Shims can be used only in a ShimsContext
    using (ShimsContext.Create())
    {
        // Arrange
        // Use shim for CloudConfigurationManager.GetSetting
        Microsoft.WindowsAzure.Fakes.ShimCloudConfigurationManager.GetSettingString = (key) =>
        {
            return "mockedSettingValue";
        };
                
        // Create the fake queue:
        // In the completed application, queue would be a real one:
        bool wasCreateFromConnString = false;
        Order orderSent = null;
        IMicrosoftAzureQueue queue =
                new OrderWebRole.Queue.Fakes.StubIMicrosoftAzureQueue() // Generated by Fakes.
                {
                    // Define each method:
                    // Name is original name + parameter types:
                    InitializeFromConnectionStringStringString = (connectionString, queueName) => {
                        wasCreateFromConnString = true;
                    },
                    SendOrder = (order) => {
                    orderSent = order;
                    }
                };

        // Component under test
        OrderController controller = new OrderController(queue);

        // Act
        Order inputOrder = new Order()
        {
            OrderId = System.Guid.NewGuid(),
            Description = "A mock order"
        };
        ViewResult result = controller.Create(inputOrder) as ViewResult;

        //Assert
        Assert.IsTrue(wasCreateFromConnString);
        Assert.AreEqual("OrderCreated", result.ViewName);
        Assert.IsNotNull(orderSent);
        Assert.AreEqual(inputOrder.OrderId, orderSent.OrderId);
        Assert.AreEqual(inputOrder.Description, orderSent.Description);
    }
}

Die Webrolle übernimmt das Hinzufügen einer Bestellung zur Warteschlange. Überlegen Sie jetzt, wie Sie eine Workerrolle testen, die die Bestellungen verarbeitet, indem sie sie aus der Service Bus-Warteschlange abruft. Die Run-Methode in unserer Workerrolle ruft regelmäßig Bestellungen aus der Warteschlange ab und verarbeitet sie.

private IMicrosoftAzureQueue queue;
public WorkerRole()
{
    queue = new MicrosoftAzureQueue();
}

public WorkerRole(IMicrosoftAzureQueue queue)
{
    this.queue = queue;
}
public override void Run()
{
    try
    {
        string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
        string queueName = "ProcessingQueue";
               
        queue.InitializeFromConnectionString(connectionString, queueName);
            
        queue.CreateQueueIfNotExists();
              
        while (true)
        {
            Thread.Sleep(2000);
            //Retrieve order from Service Bus Queue  
            TryProcessOrder(queue);
        }
    }
    catch (Exception ex)
    {
        if (queue != null)
            queue.Close();
        System.Diagnostics.Trace.TraceError(ex.Message);
    }
}

Wir benötigen nun einen Test, um zu überprüfen, ob die Routine eine Nachricht korrekt abruft. Im Folgenden finden Sie den vollständigen Test für die „Run“-Methode der Workerrolle.

[TestMethod]
public void Test_WorkerRole_Run()
{
    // Shims can be used only in a ShimsContext:
    using (ShimsContext.Create())
    {
        Microsoft.WindowsAzure.Fakes.ShimCloudConfigurationManager.GetSettingString = (key) =>
        {
            return "mockedSettingValue";
        };

        // Arrange 
        bool wasEnsureQueueExistsCalled = false;
        int numCallsToEnsureQueueExists = 0;

        // Create the fake queue:
        // In the completed application, queue would be a real one:
        bool wasConnectionClosedCalled = false;
        bool wasCreateFromConnString = false;
        bool wasReceiveCalled = false;
        int numCallsToReceive = 0;

        bool wasCompleteCalled = false;
        int numCallsToComplete = 0;
        IMicrosoftAzureQueue queue =
                new OrderWebRole.Queue.Fakes.StubIMicrosoftAzureQueue() // Generated by Fakes.
                {

                    // Define each method:
                    // Name is original name + parameter types:
                    InitializeFromConnectionStringStringString = (connectionString, queueName) =>
                    {
                        wasCreateFromConnString = true;
                    },
                    CreateQueueIfNotExists = () =>
                    {
                        wasEnsureQueueExistsCalled = true;
                        numCallsToEnsureQueueExists++;
                    },
                    Receive = () =>
                {
                    wasReceiveCalled = true;
                    if (numCallsToReceive >= 3) throw new Exception("Aborting Run");
                    numCallsToReceive++;
                    Order inputOrder = new Order()
                    {
                        OrderId = System.Guid.NewGuid(),
                        Description = "A mock order"
                    };
                    return new BrokeredMessage(inputOrder);
                },
                    Close = () =>
                    {
                        wasConnectionClosedCalled = true;
                    }

                };


        Microsoft.ServiceBus.Messaging.Fakes.ShimBrokeredMessage.AllInstances.Complete = (message) =>
        {
            wasCompleteCalled = true;
            numCallsToComplete++;
        };

        WorkerRole workerRole = new WorkerRole(queue);

        //Act
        workerRole.Run();

        //Assert
        Assert.IsTrue(wasCreateFromConnString);
        Assert.IsTrue(wasConnectionClosedCalled);
        Assert.IsTrue(wasEnsureQueueExistsCalled);
        Assert.IsTrue(wasReceiveCalled);
        Assert.AreEqual(1, numCallsToEnsureQueueExists);
        Assert.IsTrue(numCallsToReceive > 0);
        Assert.IsTrue(wasCompleteCalled);
        Assert.IsTrue(numCallsToComplete > 0);
        Assert.AreEqual(numCallsToReceive, numCallsToComplete);

    }
}

Sie sollten den Delegaten der AllInstances-Eigenschaft des generierten Fake-Typs festlegen. Durch die Verwendung des Delegaten werden alle Instanzen, die Sie von dem tatsächlichen Fake-Typ erstellen, durch alle Methoden umgeleitet, für die Sie Delegaten definiert haben.

In dem Beispiel möchten wir die „Run“-Methode der Originalinstanz verwenden, aber Umleitungen für die Instanzmethoden CreateQueue und TryProcessOrder bereitstellen. Im Code lösen wir eine Ausnahme aus, sodass die Endlosschleife verlassen wird, die von der „Run“-Methode eine vordefinierte Zeit lang aufrechterhalten wird.

Sie fragen sich vielleicht, warum wir nicht einfach die MessageSender/MessageReceiver-Klassen sowie die verwandten Klassen direkt aus dem Service Bus SDK verwenden, statt einen Hilfstyp einzufügen? Um den Code vollständig zu isolieren, damit er nicht den „echten“ Service Bus aufruft, gibt es zwei Möglichkeiten:

  • Schreiben von Fakes, die von den abstrakten Klassen im „Microsoft.ServiceBus“-Namespace erben.

  • Von Fakes für alle Klassen Pseudotypen erstellen lassen.

Das Problem bei beiden Ansätzen ist die Komplexität. Mit beiden Ansätzen müssen Sie am Ende in Klassen wie TokenProvider und QueueClient reflektieren. Reflektion verursacht folgende Probleme:

  • Sie müssen abgeleitete Typen von diesen abstrakten Typen erstellen, die alle ihre erforderlichen Überschreibungen verfügbar machen.

  • Sie müssen die internen Typen verfügbar machen, von denen die echten Versionen dieser Klassen tatsächlich abhängig sind.

  • Für die internen Typen müssen Sie deren Konstruktoren oder Factorymethoden auf geschickte Weise neu erstellen, um die Abhängigkeit vom echten Service Bus zu entfernen.

Die bessere Option besteht im Einfügen Ihres eigenen Hilfstyps. Das ist alles, was Sie benötigen, um den Code zu modellieren, umzuleiten und vom echten Service Bus zu isolieren.

Zur Analyse dessen, was diese Komponententests überprüft haben, können wir Codeabdeckungsdaten untersuchen. Wenn wir beide Komponententests mithilfe von MS Test ausführen, sehen wir, dass sie diese bestehen. Wir sehen ferner verwandte Ausführungsdetails im Test-Explorer-Dialog.

Abbildung 2

Sie können die Codeabdeckung für Ihre Tests aus dem Test-Explorer heraus ausführen. Klicken Sie mit der rechten Maustaste auf den Test, und wählen Sie Codeabdeckung für ausgewählte Tests analysieren aus. Die Ergebnisse werden im Fenster Codeabdeckungsergebnisse angezeigt. Um Datensammlung für die Codeabdeckung zu aktivieren, konfigurieren Sie die Datei „Local.testsettings“ unter den Projektmappenelementen. Wenn Sie diese Datei öffnen, wird der Testeinstellungen-Editor geöffnet.

Wenn Sie eine Projektmappe haben, die nicht die Datei „Local.testsettings“ enthält, fügen Sie sie der Projektmappe mithilfe des folgenden Verfahrens hinzu.

  1. Klicken Sie auf die Schaltfläche Neues Element hinzufügen.

  2. Wählen Sie Test aus, und klicken Sie dann auf Testeinstellungen.


    Abbildung 3

  3. Klicken Sie auf die Registerkarte Daten und Diagnose, und aktivieren Sie das Kontrollkästchen rechts neben der Zeile Codeabdeckung.

  4. Klicken Sie als Nächstes auf die Schaltfläche Konfigurieren .

  5. Wählen Sie im Fenster Codeabdeckung Detail alle Assemblys aus, die Sie testen werden, und klicken Sie auf OK.


    Abbildung 4

  6. Um den Testeinstellungen-Editor zu schließen, klicken Sie auf Anwenden und Schließen.

  7. Führen Sie Ihre Tests erneut aus, und klicken Sie auf die Schaltfläche Codeabdeckung. Ihre Codeabdeckungsergebnisse sollten wie in Abbildung 5 aussehen.


    Abbildung 5

  8. Klicken Sie auf das Symbol Codeabdeckungsfärbung anzeigen, und navigieren Sie dann nach unten zu einer Methode im Raster.

  9. Doppelklicken Sie auf die Methode. Deren Quellcode wird in einer Farbe dargestellt, die die Bereiche anzeigt, die getestet wurden. Grün zeigt an, dass der Code getestet wurde. Grau zeigt an, dass der Code teilweise oder gar nicht getestet wurde.


    Abbildung 6

Das manuelle Erstellen von Komponententests ist zwar wertvoll, doch Code Digger kann auch dabei helfen, Ihre Komponententests intelligent zu verbessern. Dies erreicht er, indem er Parameterwerte ausprobiert, die von Ihnen eventuell nicht berücksichtigt wurden. Nach der Installation von Code Digger können Sie eine Methode untersuchen, indem Sie im Code-Editor mit der rechten Maustaste auf die Methode klicken und Generate Inputs/Outputs Table auswählen.

Abbildung 7

Nach kurzer Zeit stellt Code Digger die Verarbeitung fertig, und die Ergebnisse stabilisieren sich. Abbildung 8 zeigt beispielsweise die Ergebnisse von Code Digger, der gerade die „TryProcessOrder“-Methode der Workerrolle verarbeitet. Beachten Sie, dass Code Digger in der Lage war, einen Test zu erstellen, der zu einer Ausnahme geführt hat. Code Digger zeigt außerdem die Eingaben an, die er erstellt hat, um diese Ausnahme zu generieren (ein NULL-Wert für die Warteschlange), was sogar noch wichtiger ist.

Abbildung 8

Fanden Sie dies hilfreich?
(1500 verbleibende Zeichen)
Vielen Dank für Ihr Feedback.
Anzeigen:
© 2014 Microsoft