Dieser Artikel wurde maschinell übersetzt.

Testlauf

Testen von Silverlight-Anwendungen mithilfe von Meldungen

James McCaffrey

Downloaden des Codebeispiels

Ich bin ein großer Fan von Silverlight und in der Kolumne dieses Monats beschrieben, ein Verfahren, mit dem Sie Silverlight-Anwendungen testen.

Silverlight ist eine vollständige Web Anwendungsframework, das anfänglich im 2007 veröffentlicht wurde. Die aktuelle Version Silverlight 3 wurde im Juli 2009 freigegeben. Visual Studio 2010 bietet erweiterte Unterstützung für Silverlight, insbesondere ein vollständig integrierter visueller Designer, die Silverlight entwerfen Benutzer Schnittstellen ein Kinderspiel.

Die beste Möglichkeit, damit Sie sehen, wo ich in diesem Artikel weisenden bin besteht darin, einen Blick auf die Anwendungen selbst. Abbildung 1 zeigt eine einfache, jedoch repräsentative Silverlight-Anwendung, die mit dem Namen MicroCalc. Sie können angezeigt, dass MicroCalc innerhalb von Internet Explorer gehostet wird, obwohl Silverlight-Anwendungen auch von anderen Browsern wie Firefox, Opera und Safari gehostet werden können.

Figure 1 MicroCalc Silverlight App
Abbildung 1 MicroCalc Silverlight-App

Abbildung 2 zeigt eine einfache Testumgebung, die auch eine Silverlight-Anwendung ist.


Abbildung 2 Testumgebung für MicroCalc

In diesem Beispiel wurde die erste Testfall ausgewählt. Beim Klicken auf das Schaltflächen-Steuerelement mit der Bezeichnung ausgewählte Tests durchführen wurde gesendet die Silverlight-Testumgebung eine Nachricht, die die ausgewählte Testfall Eingabedaten für die Silverlight-MicroCalc zu testende Anwendung enthält. Dieser Test Case-Daten bestehen aus Anweisungen so simulieren Sie einen Benutzer der Anwendung, die Eingabebereiche eingeben 2.5, 3.0 multiplizieren Vorgang, und klicken Sie dann auf die Schaltfläche Compute auswählen.

Die Anwendung akzeptiert die Testfalldaten und sich selbst mithilfe von Testcode, die in der Anwendung instrumentiert wird programmgesteuert ausgeübt. Nach einer kurzen Verzögerung die Testumgebung eine zweite Meldung angezeigt, die zu testende anfordern, dass die Anwendung eine Meldung mit Informationen über den Zustand der Anwendung senden, die Anwendung sendet, nämlich der Wert im Ergebnisfeld. Die Testumgebung die resultierende Meldung von der Anwendung empfangen und festgestellt, dass der tatsächliche Wert in der Anwendung 7.5000, der erwartete Wert in die Testfalldaten entsprach und Ergebnis Testfall erfolgreich in die Testumgebung Kommentare Bereich angezeigt.

In diesem Artikel wird davon ausgegangen, dass Sie über grundlegende Kenntnisse im Umgang mit der C#-Sprache, jedoch ist nicht davon aus, dass Sie Erfahrung mit Silverlight haben. In den folgenden Abschnitten dieses Artikels, beschreibe ich zuerst die zu testende Anwendung Silverlight. Ich durchlaufen Sie die Details zum Erstellen von die einfache Silverlight-basierten Testumgebung im Abbildung 1 angezeigt, und ich erläutern, wie die Anwendung instrumentieren. Ich umbrochen alternative testen Ansätze beschrieben.

Die zu testende Anwendung

Let’s sehen Sie sich den Code für die MicroCalc von Silverlight-Anwendung, die das Ziel von meinem Test Automation-Beispiel ist. Das erstellte MicroCalc mithilfe von Visual Studio 2010 Beta 2. Silverlight-3 ist vollständig in Visual Studio 2010 integriert, aber der Code, den ich hier vorstellen kann auch mit Visual Studio 2008 mit dem Silverlight-3-SDK separat installiert.

Nach dem Starten von Visual Studio, nach dem Klicken auf Datei | neu | Projekt. Beachten Sie, dass eine Silverlight-Anwendung ein .NET-Komponente, die in einer Webanwendung selbst, sondern eine Webanwendung gehostet werden kann. Im Dialogfeld Neues Projekt ich die C#-Sprache Vorlagen Option ausgewählt. Silverlight-Anwendungen können auch mit Visual Basic erstellt werden, und Sie können auch mithilfe der neuen Sprache F#-Silverlight-Bibliotheken erstellen.

Ausgewählte die Standardoption für Microsoft .NET Framework 4 Bibliothek und Silverlight Application-Vorlage. Silverlight enthält eine Teilmenge der .NET Framework, also nicht alle Teile der .NET Framework-4 für Silverlight-Anwendungen zur Verfügung stehen. Nachdem Sie den Namen (SilverCalc) und Lagerort (C:\SilverlightTesting) Felder auszufüllen, klickte ich die Schaltfläche "OK". (Beachten Sie, dass SilverCalc den Namen des Visual Studio-Projekts, und MicroCalc der Name der Anwendung ist.)

Visual Studio aufgefordert mich dann das Dialogfeld Neue Silverlight-Anwendung, die auf Silverlight Anfänger verwirrend sein kann. Let’s näher an den Optionen im Abbildung 3 .


Abbildung 3 Neue Silverlight Dialog Box Anwendungsoptionen

Der erste Eintrag, “ hosten die Silverlight-Anwendung in eine neue Website, die ” ist standardmäßig aktiviert. Dies weist Visual Studio zum Erstellen von zwei verschiedene Webseiten auf Host der Silverlight-Anwendung.

Der nächste Eintrag ist der Name des Visual Studio-Projekt, das die Host zwei Seiten enthält. Das Projekt wird der Visual Studio-Projektmappe hinzugefügt.

Der dritte Eintrag in das Dialogfeld wird ein Dropdown-Steuerelement mit drei Optionen: ASP.NET Web Application Project, ASP.NET Website und ASP.NET MVC-Webprojekt. Eine vollständige Erläuterung dieser Optionen ist außerhalb des in diesem Artikel, das Endergebnis ist jedoch, dass die beste Option für allgemeine Zwecke ASP.NET Web Application Project.

Der vierte Eintrag in das Dialogfeld wird eine Dropdownliste, wählen Sie die Silverlight-Version, in diesem Fall 3.0. Nachdem Sie auf OK, geklickt haben erstellt Visual Studio eine leere Silverlight-Anwendung.

Ich per Doppelklick auf die Datei MainPage.xaml, die XAML-basierten BENUTZEROBERFLÄCHEN-Definitionen in der Visual Studio-Editor zu laden. Durch Hinzufügen von Width und Height-Attribute und ändern das Background-Color-Attribut geändert, die Standardattribute für das Datenraster-Steuerelement der obersten Ebene:

<Grid x:Name="LayoutRoot"
  Background="PaleGreen" 
  Width="300" Height="300">

Standardmäßig nimmt eine Silverlight-Anwendung den gesamten Clientbereich in seine Hostseite. Hier festgelegt ich die Breite und Höhe auf 300 Pixel damit meine Silverlight-Anwendung, die die Standardgröße einer Windows Forms-Anwendung ähnelt. Ich angepasst, die Farbe um den Bereich belegt, die für das Silverlight-Anwendung deutlich sichtbar zu machen.

Als Nächstes verwendet habe ich Visual Studio, um die Beschriftungen, drei Textfeld-Steuerelemente, zwei RadioButton-Steuerelemente und ein Button-Steuerelement in meiner Anwendung, wie in Abbildung 1 hinzufügen. Visual Studio 2010 hat eine vollständig integrierte Entwurfsansicht, wenn ich ein Steuerelement, z. B. ein Textfeld-Steuerelement (TextBox) auf die Entwurfsoberfläche ziehen, der zugrunde liegenden XAML-Code automatisch generiert wird:

<TextBox Width="99" Height="23" Name="textBox1" ... />

Nachdem Sie die Beschriftungen und Steuerelemente auf Meine Anwendung MicroCalc haben, doppelgeklickt ich auf das Button-Steuerelement seinen Ereignishandler für das MainPage.xaml.cs-Datei hinzu. Im Code-Editor eingegeben ich den folgenden C#-Code ein, um MicroCalc seine Funktionalität zu bieten:

private void button1_Click(
  object sender, RoutedEventArgs e) {

  double x = double.Parse(textBox1.Text);
  double y = double.Parse(textBox2.Text);
  double result = 0;
  if (radioButton1.IsChecked == true)
    result = x * y;
  else if (radioButton2.IsChecked == true)
    result = x / y;
  textBox3.Text = result.ToString("0.0000");
}

Sie zunächst die Werte in der textBox1 und textBox2-Steuerelemente als Text eingegebene grabbing und konvertieren Sie die doppelte Eingabe. Beachten Sie, um das Beispiel kurz zu halten, die ich haben die normalen Fehlerprüfung ausführen in einer realen Anwendung würden ausgelassen.

Als Nächstes bestimmen ich, welches RadioButton-Steuerelement vom Benutzer ausgewählt wurde. Ich muss den voll gekennzeichneten booleschen Ausdruck verwenden:

if radioButton1.IsChecked == true

Sie haben möglicherweise erwartet, dass ich das Kontextmenü-Formular verwenden würden:

if radioButton1.IsChecked

Verwendet werden? vollqualifizierte Formular da die IsChecked-Eigenschaft des auf NULL festlegbarem Typ Bool ist Anstatt einfache Bool.

Nach computing das angezeigte Ergebnis platzieren ich das Ergebnis in das Steuerelement textBox3 auf vier Dezimalstellen formatiert.

MicroCalc ist nun bereit, um zu wechseln, und ich können drücken Sie die Taste [F5], um Visual Studio zum Ausführen der Anwendung anzuweisen. Standardmäßig werden Visual Studio Internet Explorer starten und laden Sie die zugehörigen ASPX-Host-Seite, die automatisch generiert wurde. Visual Studio eine Testseite Host Silverlight ausgeführt wird, über den integrierten Webserver für die Entwicklung, sondern über IIS. Testen zusätzlich zu einer ASPX-Seite Host, generiert Visual Studio auch eine HTML-Testseite, die manuell durch Eingeben seiner Adresse in Internet Explorer geladen werden kann.

Die Testumgebung

Nun, da Sie die zu testende Anwendung Silverlight gesehen haben, können Sie mir die Testumgebung beschrieben.

Ich habe mich entschieden, lokaler Messaging zum Senden von Nachrichten zwischen der Testumgebung und der Anwendung verwenden. Ich begann, indem Sie eine neue Instanz der Visual Studio 2010 starten. Verwenden den gleichen Prozess wie im vorherigen Abschnitt beschrieben, erstellt habe ich eine neue Silverlight-Anwendung mit dem Namen TestHarness. Als mit der Anwendung MicroCalc ich die auf der obersten Ebene Datenraster-Steuerelement, um die Standardgröße auf 300 x 300 Pixel und die Hintergrundfarbe in Bisque zu ändern, damit das Silverlight-Steuerelement deutlich abheben bearbeitet. Als Nächstes fügte ich ein Label-Steuerelement, zwei Listenfeld-Steuerelemente und ein Button-Steuerelement auf die Entwurfsoberfläche Testumgebung.

Nach dem ändern, der Inhalten-Eigenschaft des Button-Steuerelements ausgewählten Test ausführen, doppelgeklickt ich die Schaltfläche, um den Ereignishandler zu generieren. Bevor Sie den Logik Code zum Ereignishandler hinzufügen, deklarieren ich ein Gültigkeitsbereich der Klasse LocalMessageSender-Objekt und Test Case-Daten in der Datei MainPage.xaml.cs von der Testumgebung, damit die Testumgebung die zu testende Anwendung kontaktieren kann:

public partial class MainPage : UserControl {
  LocalMessageSender lms = null;
  private string[] testCases = new string[] {
    "001:2.5:3.0:Multiply:7.5000",
    "002:8.6:2.0:Divide:4.3000"
  };
...

Die LocalMessageSender-Klasse in der System.Windows.Messaging-Namespace enthalten ist, damit einen Verweis auf das mit einer using hinzugefügte-Anweisung am oberen Rand der CS-Datei so dass ich nicht um den Namen der Klasse vollständig zu qualifizieren. Verwenden einen einfachen Ansatz für meine Testfalldaten, und verwenden eine Doppelpunkt getrennten Zeichenfolge mit Feldern für den Testfall-ID, erste Eingabewert, zweite Eingabewert, Betrieb und die erwarteten Ergebnis. Als Nächstes fügen Sie Klassenvariablen Bereich Zeichenfolge für jedes Feld Testfall:

private string caseID;
private string input1;
private string input2;
private string operation;
private string expected;
...

Diese Variablen nicht technisch erforderlich sind, aber der Testcode leichter zu lesen und zu ändern.

Nachdem ich ein LocalMessageReceiver-Objekt in der MainPage-Konstruktor, instanziiert so dass meine Testumgebung Nachrichten aus der zu testenden Anwendung akzeptieren kann:

public MainPage() {
  InitializeComponent();

  try {
    LocalMessageReceiver lmr =
      new LocalMessageReceiver("HarnessReceiver",
        ReceiverNameScope.Global,
        LocalMessageReceiver.AnyDomain);
...

Der LocalMessageReceiver-Objekt-Konstruktor akzeptiert drei Argumente. Das erste Argument ist ein Name zum Identifizieren des Empfängers – Dies wird durch ein LocalMessageSender-Objekt um anzugeben, welche Empfänger zum Ziel verwendet werden. Das zweite Argument ist eine Enumeration-Typ, der angibt, ob der Empfänger Name an der globalen Domäne oder in eine stärker eingeschränkte Domäne begrenzt ist. Das dritte Argument gibt an, in dem der Empfänger akzeptiert case-Nachrichten aus, in diesem einer beliebigen Domäne.

Als Nächstes ich verbinden Sie einen Ereignishandler für den Empfänger, und starten Sie dann das Empfängerobjekt:

lmr.MessageReceived += HarnessMessageReceivedHandler;
lmr.Listen();
...

Hier angeben ich, wenn die Testumgebung eine Nachricht empfängt, Steuerelement an eine Anwendung definierte Methode mit dem Namen HarnessMessageReceivedHandler übertragen werden sollen. Die Listen-Methode, überwacht wie Sie erwarten, ständig für eingehende Nachrichten von einem LocalMessageSender in die zu testende Anwendung.

Jetzt instanziieren Sie das Sender-Objekt, das ich zuvor deklariert:

lms = new LocalMessageSender(
  "AppReceiver", LocalMessageSender.Global);
lms.SendCompleted += HarnessSendCompletedHandler;
...

Beachten Sie, dass das erste Argument für die Sender-Objekt den Namen eines Empfängers Zielobjekts, keinen kennzeichnenden Namen des Absenders ist. Hier wird mein Test Testumgebung Absender senden Nachrichten nur an einen Empfänger mit dem Namen AppReceiver in der zu testenden Anwendung befindet. Mit anderen Worten, Empfänger Objekte verfügen über Namen und Nachrichten vom Absender Objekte akzeptiert, aber Absender Objekte haben keinen Namen und sendet Nachrichten nur an bestimmte Empfänger.

Nachdem das Sender-Objekt instanziiert, verbinden ich einen Ereignishandler für das SendCompleted-Ereignis. Jetzt kann ich meine Testfälle zu laden und Behandeln von Ausnahmen:

...
    foreach (string testCase in testCases) {
      listBox1.Items.Add(testCase);
    }
  } // try
  catch (Exception ex) {
    listBox2.Items.Add(ex.Message);
  }
} // MainPage()

Ich durchlaufen einfach 
array Testfall jeden Testfall Zeichenfolge an das Steuerelement listBox1 hinzugefügt. Wenn eine Ausnahme abgefangen wird, anzeigen ich nur den Text im Steuerelement listBox2 für Kommentare verwendet.

Zu diesem Zeitpunkt habe ich einen Sender-Objekt in der Testumgebung, die Testfall Eingaben für die Anwendung und ein Empfängerobjekt in der Testumgebung senden kann, die Zustandsinformationen aus der Anwendung akzeptieren kann. Jetzt gehen ich Sie zurück zu der Button1_Click-Ereignishandler-Methode, die ich zuvor hinzugefügt. In den Ereignishandler zunächst ausgewählte Testfall analysiert werden:

string testCaseData = (string)listBox1.SelectedItem;
string[] tokens = testCaseData.Split(':');
caseID = tokens[0];
input1 = tokens[1];
input2 = tokens[2];
operation = tokens[3];
expected = tokens[4];
...

Jetzt bin ich bereit, Test Case-Eingabe für die zu testende Anwendung Silverlight zu senden:

string testCaseInput = 
  input1 + ":" + input2 + ":" + operation;
listBox2.Items.Add("========================");
listBox2.Items.Add("Test case " + caseID);
listBox2.Items.Add(
  "Sending ‘" + testCaseInput + "’ to application");
lms.SendAsync("data" + ":" + testCaseInput);
...

Ich montieren wieder zusammen nur Testfall Eingabe. Ich senden den Testfall-ID oder der erwartete Wert für die Anwendung nicht da nur die Testumgebung mit diesen Werten behandelt. Nach der Anzeige einige Kommentare an das Steuerelement listBox2, verwende ich die SendAsync-Methode des Objekts LocalMessageSender, um Test Case-Daten zu senden. Ich voran die Zeichenfolge “ Daten ”, so dass die Anwendung hat eine Methode zum Identifizieren, welche Art von Nachricht empfangen wird.

Meine Schaltfläche-Ereignishandler wird beendet, indem eine Sekunde anhalten, um die Anwendungszeit ausgeführt hat, und ich senden eine Nachricht mit der Frage an, der Anwendung für die Zustandsinformationen:

System.Threading.Thread.Sleep(1000); 
  lms.SendAsync(“response”);
} // button1_Click

Denken Sie daran, dass ich einen Ereignishandler für die Vervollständigung von senden verdrahtet, aber in diesem Entwurf nicht explizit post-send Verarbeitungen durchführen muss.

Der letzte Teil der Testumgebung Code befasst sich mit der Nachricht, die von der Silverlight-Anwendung, um die Testumgebung gesendet:

private void HarnessMessageReceivedHandler(object sender,
  MessageReceivedEventArgs e) {

  string actual = e.Message;
  listBox2.Items.Add(
    "Received " + actual + " from application");
  if (actual == expected)
    listBox2.Items.Add("Pass");
  else
    listBox2.Items.Add("**FAIL**");

  listBox2.Items.Add("========================");
}

Hier die Nachricht aus der Anwendung, die ist der Wert im Steuerelement textBox3 Ergebnis, und speichern Sie diesen Wert in eine Variable, die mit dem Namen abrufen aktueller. Nach der Anzeige eines Kommentars, vergleichen ich den tatsächlichen Wert, der von der Anwendung, mit dem erwarteten Wert analysiert von Testfalldaten gesendet wurde zu bestimmen und ein Testfall Erfolg/Misserfolg Ergebnis anzuzeigen.

Durch das Instrumentieren der Silverlight-Anwendungs

Jetzt let’s untersuchen den instrumentierten Code innerhalb der Silverlight-Anwendung getestet. Zunächst deklarieren ein Gültigkeitsbereich der Klasse LocalMessageSender-Objekt.

Dieses Absenders sendet Nachrichten an die Testumgebung:

public partial class MainPage : UserControl {
  LocalMessageSender lms = null;
  public MainPage() {
    InitializeComponent();
...

Ich als Nächstes dem Empfänger in der MainPage-Konstruktor, akzeptieren Sie Nachrichten aus der Testumgebung Draht einen Ereignishandler zu instanziieren und Starten der Überwachung für Nachrichten aus der Testumgebung:

try {
  LocalMessageReceiver lmr =
    new LocalMessageReceiver("AppReceiver",
      ReceiverNameScope.Global,
      LocalMessageReceiver.AnyDomain);
  lmr.MessageReceived += AppMessageReceivedHandler;
  lmr.Listen();
...

Wie zuvor, beachten Sie, dass die Empfängerobjekt einen Namen zuweisen und diesen Namen das erste Argument für die Sender-Objekt in der Testumgebung entspricht. Anschließend behandeln ich alle Ausnahmen:

...
  }
  catch (Exception ex) {
    textBox3.Text = ex.Message;
  }
} // MainPage()

Ich Fehlermeldungen Ausnahme im Feld Ergebnis Anwendung MicroCalc ist textBox3-Steuerelement. Dieser Ansatz ist vollständig ad-hoc-, aber die Ausnahmemeldung an die Testumgebung sendet möglicherweise nicht durchführbar, wenn der messaging Code die Ausnahme auslöst. Jetzt behandeln Sie Nachrichten, die durch die Testumgebung gesendet:

private void AppMessageReceivedHandler(object sender,
  MessageReceivedEventArgs e) {
  string message = e.Message;
  if (message.StartsWith("data")) {
    string[] tokens = message.Split(‘:’);
    string input1 = tokens[1];
    string input2 = tokens[2];
    string operation = tokens[3];
...

Die Testumgebung sendet zwei Arten von Meldungen. Testfall input Daten beginnt mit “ Daten ”, während eine Anforderung für Anwendungszustand nur “ Antwort ”. Ich verwende die StartsWith-Methode, um zu bestimmen, ob die Nachricht, die von der Anwendung empfangenen Testfall Eingabe ist. Wenn dies der Fall ist, verwende ich die Split-Methode, um die Eingabe in Variablen mit beschreibenden Namen zu analysieren.

Die Instrumentation verwendet jetzt den Testfall, die Eingabe, um Benutzeraktionen zu simulieren:

textBox1.Text = input1;
textBox2.Text = input2;
if (operation == "Multiply")
  radioButton1.IsChecked = true;
else if (operation == "Divide")
  radioButton2.IsChecked = true;
...

Im Allgemeinen ist Ändern der Eigenschaften von Steuerelementen, z. B. Text und die IsChecked-Eigenschaft in diesem Beispiel wird der Benutzereingabe simulieren einfach. Simulieren von Ereignissen, z. B. Klicks erfordert jedoch einen anderen Ansatz:

button1.Dispatcher.BeginInvoke(
  delegate { button1_Click(null,null); });

Die Dispatcher-Klasse ist Teil der Windows.Threading-Namespace, daher eine using hinzugefügte-Anweisung mit Verweis auf die Klasse, um die Anwendung. Die BeginInvoke-Methode können Sie eine Methode für das Silverlight-Benutzeroberflächenthread asynchron aufzurufen. BeginInvoke akzeptiert einen Delegaten, der einen Wrapper für eine Methode ist. Hier verwenden Sie das Feature anonymer Delegat um meinen Aufruf zu vereinfachen. BeginInvoke gibt ein DispatcherOperation-Objekt zurück, aber ich können in diesem Fall sicher, dass Wert ignoriert.

Die Dispatcher-Klasse verfügt außerdem über eine CheckAccess-Methode, die Sie verwenden können, um zu bestimmen, ob BeginIvoke erforderlich ist (Wenn CheckAccess false zurückgibt) oder ob Sie einfach einer Eigenschaft ändern können (CheckAccess gibt true zurück).

Ich vollständig Meine Instrumentation von Umgang mit der Meldung aus der Testumgebung, die der Anwendungszustand anfordert:

...
  }
  else if (message == "response") {
    string actual = textBox3.Text;
    lms.SendAsync(actual);
  }
} // AppMessageReceivedHandler()

Wenn die Nachricht empfangen nur die Zeichenfolge “ Antwort ” ist, können Sie den Wert im Steuerelement textBox3 abrufen und senden Sie Sie wieder in der Testumgebung.

Das Testsystem, die in diesem Artikel beschrieben ist nur eine der vielen Ansätze können verwendet und eignet sich am besten für 4-4-4 ultra-light Testautomatisierung.Damit ich meine eine Testumgebung, die eine erwartete Nutzungsdauer von 4 Wochen oder weniger hat, besteht aus 4 Seiten oder weniger Code und erfordert 4 Stunden oder kleiner zu erstellen.

Der Hauptvorteil von Tests mit Nachrichten, die im Vergleich zu anderen Ansätzen ist, dass die Technik sehr einfach ist.Der wichtigste Nachteil ist, dass die zu testende Anwendung stark, instrumentiert werden muss, kann nicht immer möglich sein.

Die Technik, die ich hier dargestellten haben zwei wichtige alternativen sind die HTML-Bridge mit JavaScript und unter Verwendung der Microsoft UI Automation-Bibliothek verwenden.Wie üblich, werde ich Sie, dass kein anderer bestimmte Tests Ansatz eignet sich besonders für alle Situationen, aber der Nachrichten basierenden Ansatz, der hier vorgestellten kann eine effiziente und effektive Technik in vielen Szenarios der Software-Entwicklung erinnern.

Dr. James McCaffrey  arbeitet für Volt Information Sciences Inc., wo er technische Schulungen für Softwareentwickler bei Microsoft Redmond, Washington, verwaltet Campus. Er hat an verschiedenen Microsoft-Produkten, einschließlich Internet Explorer und MSN Search gearbeitet. Dr. McCaffrey ist Autor von “ .NET Test Automation Recipes ” (Apress, 2006). Er kann unter jammc@microsoft.com erreicht werden.

Dank an die folgenden technischen Experten für die Überprüfung dieses Artikels: Karl Erickson und Nitya Ravi