MSDN Magazin > Home > Ausgaben > 2006 > November >  Test Run: Verwenden von Excel für Testdate...
Test Run
Verwenden von Excel für Testdaten
Dr. James McCaffrey

Codedownload verfügbar unter: TestRun2006_11.exe (171 KB)
Browse the Code Online
Wenn Sie eine Testautomatisierung schreiben, stehen Ihnen vier sich ergänzende Vorgehensweisen zur Verfügung: Sie kaufen und benutzen ein kommerzielles Testframework (einschließlich Visual Studio® 2005 Team System, das einige praktische neue Funktionen aufweist), Sie nutzen ein Open Source-Testframework, Sie schreiben eine benutzerdefinierte aufwändige Automatisierung (im Allgemeinen mehr als vier Seiten Code), oder Sie schreiben eine vereinfachte Automatisierung (im Allgemeinen weniger als vier Seiten Code). Die meisten meiner Artikel über den Testlauf befassen sich mit Verfahren für vereinfachte Automatisierung. Beim Schreiben einer vereinfachten Testautomatisierung ist Microsoft® Excel® eine der besten Möglichkeiten für die Speicherung von Testfalldaten und Testergebnissen.
Im Artikel dieses Monats erfahren Sie, wie sich Excel zur Speicherung von Testautomatisierung verwenden lässt. Obwohl er sich an Entwickler wendet, die mit ihren Kenntnissen auf dem Gebiet der .NET-Programmierung noch am Anfang stehen, können die hier dargestellte Informationen sicher auch für Programmierer mit mittlerer oder umfangreicher Erfahrung interessant und recht nützlich erscheinen.
Stellen Sie sich vor, Sie schreiben gerade ein Cribbage-Spiel wie das in Abbildung 1 dargestellte. Beim Cribbage spielen Sie mit fünf Karten, vier halten Sie in der Hand, und eine teilen Sie mit Ihrem Gegner. Die von Ihnen erreichte Punktzahl hängt von mehreren Faktoren ab, wie etwa der Anzahl von Kartenpaaren in Ihrer Hand und der Anzahl Ihrer Kartenkombinationen, deren Summe 15 ergibt. Jedes Paar ist 2 Punkte wert, und jede Kombination mit der Summe 15 ist 2 Punkte wert. Bildkarten zählen 10, Asse zählen 1, und bei allen anderen Karten zählt deren Punktwert. Bei dem in Abbildung 1 gezeigten Spiel beträgt der Wert der Paare 2, da es ein einziges Paar Siebenen gibt. Der Wert der Fünfzehner-Kombinationen ist 6, da es 3 Kartenkombinationen mit der Summe 15 gibt: Karo Sieben und Kreuz Acht; Kreuz Sieben und Kreuz Acht; Karo Sieben, Kreuz Sieben und Herz As.
Abbildung 1 Die zu testende Anwendung 
Im Hintergrund ruft die Benutzeroberfläche des Spiels eine CribbageLib-Klassenbibliothek auf, die Sie geschrieben haben. Diese Bibliothek enthält Klassen zur Darstellung eines Kartenobjekts und eines Handobjekts sowie Methoden und Eigenschaften wie Hand.ValueOfPairs und Hand.ValueOf15s.
In diesem Artikel lernen Sie Techniken kennen, wie Sie Excel zum Festhalten von Testfalldaten und Speichern von Testergebnissen nutzen können, so wie im Programm in Abbildung 2. Das vereinfachte Testprogramm beginnt mit der Prüfung, ob die Excel-Tabelle, die Testfalldaten enthält, vorhanden ist. (An dieser Stelle soll kurz erklärt werden, wie Sie eine Excel-Tabelle so erstellen, dass Sie Daten programmgesteuert aus ihr lesen können.) Als Nächstes durchsucht das Programm die Exceldaten, um die Anzahl der Testfälle festzustellen, und liest dann alle Exceldaten in ein im Speicher befindliches DataTable-Objekt. (Das Alternativverfahren, das im Einlesen von jeweils nur einem Testfall besteht, wird im letzten Abschnitt dieses Artikels behandelt.) Das Programm erstellt eine neue Excel-Tabelle zum Festhalten der Testfalldaten und führt dann jeden Testfall einzeln durch. Das Programm stellt für jeden Test ein Ergebnis fest (pass/fail), gibt das Ergebnis auf der Konsole aus und speichert es in der Excel-Tabelle. Der vollständige Quellcode für das Testprogramm und die zu testende Bibliothek befinden sich im herunterladbaren Code zu diesem Artikel.
In den folgenden Abschnitten soll die zu testende Klassenbibliothek beschrieben werden, damit Sie sehen, wie man eine geeignete Excel-Tabelle zum Speichern erstellt. Vorgestellt wird der Code für das einfache Testprogramm, das die in Abbildung 2 gezeigten Ergebnisse erzeugt. Der Code wird ausführlich erläutert, sodass Sie in die Lage versetzt werden, ihn so zu verändern oder auszubauen, wie Sie ihn für die Nutzung von Excel für Ihre individuellen Bedürfnisse brauchen. Und schließlich soll noch ganz kurz erörtert werden, wie und wann Excel zur Testspeicherung zu verwenden ist, wobei die Pros und Contras dieser Verfahrensweise im Vergleich zu anderen Arten von Testspeicherung (SQL Server™-Datenbanken, Textdateien und insbesondere XML-Dateien) betrachtet werden. Sie werden sicher lernen, Excel für vereinfachte Testspeicherung als nützliche Ergänzung Ihres Test-, Entwicklungs- und Verwaltungs-Softwaretoolkits zu nutzen.
Abbildung 2 Verwenden von Excel zum Speichern von Testdaten(Klicken, um die Ansicht zu vergrößern) (Klicken Sie zum Vergrößern auf das Bild)

Die zu testende Bibliothek
Um eine Softwarekomponente mit Automatisierung zu testen, müssen Sie gewisse Mindestkenntnisse über die Schnittstellen der Komponente haben. Der Code in Abbildung 3 zeigt die Struktur meiner CribbageLib-Klassenbibliothek. Es ist hervorzuheben, dass beim vorliegenden Beispiel die Standardrichtlinien für .NET-Codierung absichtlich nicht eingehalten wurden, um die zu testende Bibliothek klein halten zu können.
using System;
namespace CribbageLib
{
  public class Card
  {
    public int rank;  // 0 = Ace, 1 = Deuce, . . , 12 = King
    public int suit;  // 0 = Clubs, 1 = Diamonds, 2 = Hearts, 3 = Spades
    public int value;  // Ace = 1, Deuce = 2, . . , Jack/Queen/King = 10
    public string image;  // "Ac", "9h", etc.

    public Card(string c)
    {
      // create Card from string c
    }

    public override string ToString()
    {
      return image;
    }
  } // class Card

  public class Hand
  {
    Card[] cards;

    public Hand(Card c1, Card c2, Card c3, Card c4, Card c5)
    {
      cards = new Card[5];
      cards[0] = c1;
      cards[1] = c2;
      cards[2] = c3;
      cards[3] = c4;
      cards[4] = c5;
    }

    public override string ToString()
    {
      return "{ " + cards[0].ToString() + " " +
             cards[1].ToString() + " " + cards[2].ToString() + " " +
             cards[3].ToString() + " " + cards[4].ToString() + " }";
    }

    public int ValueOf15s { get { /* return point value */ } }

    public int ValueOfPairs { get { /* return point value */ } }
  } // class Hand
} // ns CribbageLib
Die CribbageLib-Bibliothek enthält eine Card-Klasse, mit der sie eine einzelne Karte darstellen kann. Ich verwende die Ganzzahlfelder „rank“, „suit“ und „value“ dafür, den Rang (wie As, Zwei, Drei), die Farbe (Kreuz, Karo, Herz, Pik) und den Wert beim Cribbage darzustellen (Asse sind 1 Punkt wert, Zweien 2 und Bildkarten 10 Punkte). Der Card-Konstruktor nimmt eine Zeichenkette entgegen (wie etwa "Ac" für das Kreuz As), analysiert die beiden eingegebenen Zeichen und speichert Werte für die drei zugehörigen Member-Felder. Für die Übersichtlichkeit ist es beim Schreiben einer „ToString()“-Methode empfehlenswert, auch ein Zeichenkettenfeld namens „image“ zu speichern, das nur das Eingabeargument ist. Die Hand-Klasse ist im Wesentlichen eine Anordnung von fünf Kartenobjekten, welche die vier Karten in der Hand eines Spielers und die von beiden Spielern geteilte gemeinsame Karte darstellt. Der Hand-Konstruktor nimmt fünf Kartenobjekte an.
Der Kern der zu testenden CribbageLib-Klassenbibliothek besteht aus den Eigenschaften Hand.ValueOf15s und Hand.ValueOfPairs. Diese Eigenschaften geben den Punktwert für die Anzahl von Fünfzehnerkombinationen unter den Karten in einer Hand und den Punktwert für die Anzahl von Paaren in einer Hand zurück. Obwohl die CribbageLib-Bibliothek nur als Muster zum Testen dient, stellen die Eigenschaften von ValueOf15s und ValueOfPairs auch für sich genommen recht interessante kleine Probleme. Ich habe tatsächlich gesehen, wie diese als lohnende Interviewfragen verwendet wurden. Was jedoch diesen Artikel betrifft, brauchen Sie für die Verwendung von Excel für vereinfachte Testspeicherung die Implementierungsdetails der Eigenschaften nicht zu kennen. Sie können die Eigenschaften als Black Boxes behandeln, die für eine bestimmten Eingabe Ergebnisse erwartet haben.

Die Datei „Testfalldaten“
Üblicherweise erstellen Sie Ihre Excel-Datendateien manuell, wenn Sie die Speicherung von Testfalldaten bei vereinfachter Testautomatisierung in Excel vornehmen (gleich erfahren Sie auch, wie Excel-Dateien programmatisch erstellt werden). Die manuelle Erstellung einer Excel-Tabelle für Testfalldaten erfolgt wie die Erstellung einer Tabellenkalkulation für einen beliebigen anderen Zweck, aber mit einigen zusätzlichen Schritten. Da dieses Testprogramm für den programmatischen Zugriff auf Excel OLE DB-Technologie nutzt, müssen zur Identifikation jeder Spalte Bezeichnungen für die SpaltenkopfzeiIen angegeben werden, sodass sich Abfragen schreiben lassen. Es ist in der Tabelle auch ein benannter Bereich zu erstellen, der einem SQL-Tabellennamen entspricht.
Für dieses Beispiel möchte ich eine Testfall-ID-Nummer speichern (wie "00001"), einen Testfall-Eintrag (wie "Ah7d7c8cJs") zur Darstellung der Karten in der Hand, einen Wert, um anzuzeigen, zu welcher Klasseneigenschaft der Eintrag gehören soll (wie "Wert15er"), sowie ein erwartetes Ergebnis (wie "6"). Starten Sie also Excel, tippen Sie manuell geeignete Spaltennamen ein ("Fall-ID", "Eintrag", "Methode" und "Erwartet"), und geben Sie manuell die Testfalldaten ein. Um Ihrer Tabelle einen virtuellen Tabellennamen zuzuweisen, wählen Sie die Zellen der SpaltenkopfzeiIen (Zellen A1 bis einschließlich D1 im dargestellten Fall), und schreiben Sie dann einen Tabellennamen in das Excel-Namensfeld in der oberen linken Ecke der Tabelle. Im dargestellten Fall wurde die Tabelle, wie in Abbildung 4 zu sehen, „tblTestCases“ genannt.
Abbildung 4 Testfalldaten in Excel(Klicken, um die Ansicht zu vergrößern) (Klicken Sie zum Vergrößern auf das Bild)
Obwohl es nicht zwingend erforderlich ist, empfiehlt es sich, dem Arbeitsblatt denselben Namen zu geben wie der Tabelle. Beim programmatischen Zugriff auf Excel-Daten wird mit dem Namen im Namenfeld (und nicht dem Arbeitsblattnamen) bestimmt, auf welche Daten Bezug genommen wird. Aber wie Sie gleich sehen werden, erhält bei der programmatischen Erstellung einer Excel-Tabelle das Arbeitsblatt denselben Namen, der auch dem Namenfeld zugewiesen wurde. Daher ist es konsistenter, ein Arbeitsblatt mit manuell erstellten Excel-Testdaten umzubenennen, als den Namen „Tabelle 1“ beizubehalten.
Wenn Sie sich die Excel-Tabelle in Abbildung 4 genau ansehen, stellen Sie fest, dass alle Testfalldaten als Text eingegeben wurden. So ist beispielsweise das erwartete Ergebnis für den ersten Testfall eine als Text formatierte 6 und keine als Zahl formatierte 6. Dies wird durch das kleine grüne Dreieck in Zelle D2 angezeigt. Es wird empfohlen, alle Testfalldaten als Text zu speichern und anschließend Daten, die keine Zeichenketten sind, programmatisch in den geeigneten Datentyp im Testprogramm zu konvertieren. Das Excel-Datenmodell ist nicht das gleiche wie das .NET-Datenmodell. Es ist im Allgemeinen leichter, alle Datentypkonversionen im Programm durchzuführen, als zu versuchen, Datentypen so genau wie möglich in die Tabelle einzutragen.

Erstellen des Testprogramms
Zum Zweck der Klarheit wurde der für die Ausführung mehrerer Aufgaben benutzte Code mit Excel-Testfalldaten zu einem einzigen Testprogramm kombiniert. Abbildung 5 zeigt die Struktur des Testprogramms, das die in Abbildung 2 gezeigte Ausgabe generiert hat.
using System;
using System.IO; 
using System.Data;
using System.Data.OleDb; 
using CribbageLib;

namespace CribbageLibTest
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        Console.WriteLine("\nBegin lightweight test harness with " +
            "Excel storage demo\n");
        Console.WriteLine("Verifying Excel test case data exists");
        if (!File.Exists("..\\..\\..\\TestCases.xls"))
          throw new Exception("Test case data not found");
        else Console.WriteLine("Found test case data");

        Console.WriteLine("Determining number of test cases");
        ... // probe Excel test case data code here
        Console.WriteLine("Number of test cases = " + count);

        Console.WriteLine("Reading all test case data from Excel " +
            "into memory");
        ... // read all test case data code here
        Console.WriteLine("All test case data now in memory");

        Console.WriteLine("\nCreating Excel test case results file");
        ... // create Excel code here
        Console.WriteLine("Results file is " + resultsFile);

        Console.WriteLine("\nExecuting CribbageLib tests\n");
        ... // connect to Excel test results data here
               
        string caseid, input, method, result;
        int actual, expected;
        Console.WriteLine("caseID  input method  expected  case result");
        Console.WriteLine("===========================================");
        for (int row = 0; row < dt.Rows.Count; ++row) // main test loop
        {
          ... // read test case, execute, print result, 
              // save result to Excel
        }

        Console.WriteLine("\nAll test results stored to Excel\n");
        Console.WriteLine("End Excel as test storage demo\n");
      }
      catch (Exception ex)
      {
        Console.WriteLine("Fatal error: " + ex.Message);
      }
      Console.ReadLine();
    } // Main()
  } // class Program
} // ns CribbageLibTest
Zu Beginn des Testprogramms wird der CribbageLib.dll-Komponente, welche die zu testende Bibliothek enthält, ein Projektverweis hinzugefügt. Dann wird eine using-Anweisung für die Namespaces in der Bibliothek hinzugefügt, sodass sich auf die Klassen Card und Hand verweisen lässt, ohne sie mit ihren vollen Namen bezeichnen zu müssen. Zusätzlich wird dem System.Data.OleDb-Namespace eine using-Anweisung hinzugefügt, in der die Klassen enthalten sind, mit denen zu OLE DB-Datenquellen einschließlich Excel-Tabellen die Verbindung hergestellt werden, auf diese zugegriffen oder sie bearbeitet werden kann. Außerdem wurde dem System.Data-Namespace eine using-Anweisung hinzugefügt, sodass sich ein DataTable-Objekt leicht im Speicher für die Testfalldaten aus Excel instanziieren und nutzen lässt. Da dieser Artikel in erster Linie als Lernprogramm dient, wird der Einfachheit halber das Testprogramm als eine einfache Main-Methode gestaltet; Sie können sich jedoch überlegen, Ihr Programm modularer aufzubauen.
Geben Sie zunächst eine Startmeldung auf der Konsole aus, und wenden Sie dann die statische File.Exists-Methode an, um zu prüfen, ob die Excel-Testfalldaten am erwarteten Ort gespeichert sind. (Zur Vereinfachung dieses Beispiels wurde der größte Teil des Fehlerprüfcodes entfernt, den Sie in einer Produktionsumgebung brauchen würden.) Sobald Sie wissen, dass Ihre Testfalldaten vorhanden sind, untersuchen Sie die Excel-Tabelle, und stellen Sie fest, in wie vielen Zeilen Daten enthalten sind:
int count;
string probeConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                      "Data Source=testCases.xls;" +
                      "Extended Properties=\"Excel 8.0;HDR=YES\"";
using(OleDbConnection probeConn = new OleDbConnection(probeConnStr))
{
    probeConn.Open();
    string probe = "SELECT COUNT(*) FROM [tblTestCases$A1:A65536] " +
                    "Where caseID IS NOT NULL";
    using(OleDbCommand probeCmd = new OleDbCommand(probe, probeConn))
    {
        count = (int)probeCmd.ExecuteScalar();
    }
}
Hier wird eine Verbindungszeichenkette erstellt, die den zugehörigen OLE DB-Provider, den Speicherort sowie die Hilfsinformation bezeichnet. Achten Sie sorgfältig auf die Syntax. Beachten Sie, dass in der Eigenschaft „Extended Attributes“ eine \" -Folge dazu verwendet wird, in die Verbindungszeichenkette ein doppeltes Anführungszeichen einzubetten. Das Attribut „HDR=YES“ zeigt an, dass das Excel-Arbeitsblatt eine Anfangs-Kopfzeile hat. Der Teil "Excel 8.0" bezieht sich nicht direkt auf die Version des Excel-Programms auf dem verwendeten Computer, sondern auf das installierte Format der Jet-Datenbank ISAM (Indexed Sequential Access Method). Sie können die ISAM-Version auf Ihrem Gerät feststellen, indem Sie die Systemregistrierungseinstellung „HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\ISAM Formats“ anzeigen. Anschließend erstellen Sie ein OleDbConnection-Objekt, indem Sie die Verbindungszeichenkette an den Konstruktor übergeben. Rufen Sie die Open-Methode auf, um eine Verbindung zur Excel-Tabelle dieses Artikels herzustellen. Dann wird eine Auswahlzeichenfolge erstellt, welche die Anzahl der Nicht-NULL-Zeilen in der Tabelle zurückgibt, was mit der Anzahl der Testfälle gleichbedeutend ist, da die Kopfzeile in den zurückgegebenen Wert nicht einfließt. Dies setzt natürlich voraus, dass es in den Excel-Testfalldaten keine leeren Zeilen gibt. Beachten Sie die etwas ungewöhnliche Syntax in der SELECT-Anweisung, die sich auf die Excel-Daten bezieht. Die virtuelle Tabelle wird mit eckigen Klammern umgeben, und an den virtuellen Tabellennamen wird ein $-Zeichen angehängt. Bezeichnet wird ein Bereich von A1:A65536, da 65536 die größte Zeilenanzahl ist, die in einem Excel-Arbeitblatt unterstützt wird. Und schließlich kommt die ExecuteScalar-Methode der OleDbCommand-Klasse zur Anwendung, wodurch sich der Rückgabewert der Testfallanzahl in einer Variablen mit dem Namen „count“ ermitteln lässt. Der Untersuchungscode wird durch Schließen der OleDbConnection beendet.
Jetzt kann die Excel-Tabelle wieder aufgerufen und alle Testfalldaten aus Excel folgendermaßen in den Speicher eingelesen werden:
string tcdConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                    "Data Source=testCases.xls;" +
                    "Extended Properties=\"Excel 8.0;HDR=YES\"";
using(OleDbConnection tcdConn = new OleDbConnection(tcdConnStr))
{
    tcdConn.Open();
    int lastRow = count + 1;
    string select = "SELECT * FROM [tblTestCases$A1:D" + lastRow + "]";
    OleDbDataAdapter oda = new OleDbDataAdapter(select, tcdConn);
    DataTable dt = new DataTable();
    oda.FillSchema(dt, SchemaType.Source);
    oda.Fill(dt);
}
Aus diesem Ausschnitt entsteht eine neue Verbindungszeichenkette. Man könnte die selbe Zeichenkettenvariable wie bei der Untersuchung der Testfallanzahl verwenden; wenn jetzt eine andere Zeichenkettenvariable genutzt wird, dann nur aus Gründen der Klarheit und damit es für Sie leichter ist, den hier genannten Code zu modularisieren, falls Sie das wünschen. Als Nächstes wird ein neues OleDbConnection-Objekt erstellt. Auch hierbei könnte das für die Untersuchung der Testfallzählung genutzte Verbindungsobjekt wieder verwendet werden. Nach Eröffnung der Verbindung wird die letzte Zeile der Testfalldaten berechnet, indem zur Anzahl der tatsächlichen Testfälle in der Exceltabelle die Zahl 1 hinzugezählt wird – die zusätzliche 1 steht für die Kopfzeile. Dann wird eine SELECT-Zeichenfolge hergestellt, indem man den ersten Teil der Auswahl mit der Variablen verknüpft, welche die Nummer der letzten Testfalldaten-Zeile enthält.
Um das im Speicher befindliche DataTable-Objekt mit Testfalldaten zu befüllen, müssen Sie einen OleDbDataAdapter erstellen. Dann instanziieren Sie ein neues DataTable-Objekt, um alle Testfalldaten festzuhalten. Konfigurieren Sie mit der FillSchema-Methode des OleDbDataAdapters die DataTable-Attribute so, dass sie mit der Excel-Datenquelle konform sind. Rufen Sie dann die Fill-Methode auf, die dann die Testfalldaten aus Excel in den Speicher überträgt. Und beenden Sie die Untersuchung, indem Sie die OleDbConnection schließen. Sehr sauber und einfach.

Speichern von Ergebnissen
Nachdem Sie jetzt alle Testfalldaten in den Speicher übertragen haben, sind Sie bereit, eine neue Excel-Tabelle zur Speicherung der Testfallergebnisse zu erstellen. Der Code ist ähnlich wie bei den anderen Excel-Aufgaben, außer dass dieses Mal ein OleDbCommand-Objekt genutzt wird (siehe Abbildung 6).
string stamp = DateTime.Now.ToString("s");
stamp = stamp.Replace(":", "-");
string resultsFile = "testResults" + stamp + ".xls";

string tcrConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                    "Data Source=" + resultsFile + ";" +
                    "Extended Properties=\"Excel 8.0;HDR=YES\"";
using(OleDbConnection tcrConn = new OleDbConnection(tcrConnStr))
{
    tcrConn.Open();
    string create = "CREATE TABLE tblResults (caseID char(5),
                     Result char(4), WhenRun DateTime)";
    using(OleDbCommand createCmd = new OleDbCommand(create, tcrConn))
    {
        createCmd.ExecuteNonQuery();
    }
}
Beginnen Sie mit dem Abruf von Systemdatum und -uhrzeit, sodass Sie einen Dateinamen für Ergebnisse mit Zeitstempel erstellen können. Fügen Sie ein "s"-Argument in die „ToString()“-Methode ein, sodass Sie für Datum und Uhrzeit eine Zeichenkette in einem sortierbaren Format erhalten (wie etwa 2006-07-23T16:56:44). Da jedoch das Zeichen: in einem Dateinamen nicht gültig ist, ersetzen Sie mit der String.Replace-Methode alle : -Zeichen durch Bindestriche.
Die Verbindungszeichenkette ähnelt den beiden anderen, die Sie bereits verwendet haben, außer dass Sie den Dateinamen mit Zeitstempel darin einbetten. Stellen Sie dann die Verbindung zu einer neuen Excel-Datei her. Die Datei gibt es noch nicht wirklich, sodass Sie sich dies als eine Art von virtueller Verbindung vorstellen können.
Als Nächstes stellen Sie eine SQL-ähnliche CREATE-Zeichenkette her, und geben Sie dabei den virtuellen Tabellennamen „tblResults“ an. Beachten Sie, dass Sie für jede Spalte den Datentyp spezifizieren können. Seien Sie dabei etwas vorsichtig, da sich viele SQL-Datentypen nicht genau Excel-Datentypen zuordnen lassen. Ein alternatives Vorgehen besteht darin, einfach die Ergebnisdatei so zu benennen, dass alle Spalten vom Typ „varchar“ sind. Falls Sie irgendeine numerische Analyse Ihrer Testergebnisse in Excel durchführen möchten (zum Beispiel die Berechnung eines Durchschnitts- oder Höchstwerts), können Sie dann die Spalten, die Sie gerade analysieren, manuell in den passenden Excel-Typ umformatieren (wie etwa Zahl oder Prozentsatz).
In diesem Beispiel werden die Testfall-ID und das Testergebnis als "pass" oder "fail" gespeichert, sowie eine DateTime-Variable, welche die Uhrzeit enthält, zu der der Testfall ausgeführt wurde. Instanziieren Sie schließlich ein OleDbCommand-Objekt, und wenden Sie die ExecuteNonQuery-Methode an. Wie zuvor erwähnt, erstellt dieses Verfahren eine Excel-Tabelle, die ein Arbeitsblatt mit dem Namen „tblResults“ enthält, zu dem ein benannter Bereich „tblResults“ gehört.
Nachdem nun die Testfalldaten im Speicher sind und die Excel-Ergebnisdatei erstellt ist, sind Sie zum Durchführen Ihrer Tests und zum Speichern der Ergebnisse bereit. Beginnen Sie mit der Herstellung einer Verbindung zur neu erstellten Excel-Ergebnisdatei wie nachfolgend gezeigt:
Console.WriteLine("\nExecuting CribbageLib tests\n");
string insertConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;" +
                       "Data Source=" + resultsFile + ";" +
                       "Extended Properties=\"Excel 8.0;HDR=YES\"";
using(OleDbConnection insertConn = new OleDbConnection(insertConnStr))
{
    insertConn.Open();
    OleDbCommand insertCmd = new OleDbCommand();
    insertCmd.Connection = insertConn;
Das Nächste ist die Erstellung eines INSERT-Befehls, den Sie nach der Feststellung, ob ein Testfall erfolgreich durchgeführt wurde oder fehlgeschlagen ist, zum Einfügen eines Testergebnisses nutzen.
Erstellen Sie anschließend Ihre Testprogramm-Variablen, und drucken Sie dann eine einfache Ergebniskopfzeile. Sie können Zeichenkettenvariablen angeben, um die Testfall-ID, den Testfall-Eintrag, die zu testende Methode (oder Eigenschaft in diesem Beispiel) sowie einen Indikator für das Ergebnis ("pass" oder "fail") festzuhalten. Hier werden die Ganzzahl-Variablen „expected“ und „actual“ angegeben, um den erwarteten Rückgabewert aus der zu testenden Methode (der in der im Speicher befindlichen DataTable gespeichert ist) und den tatsächlich Rückgabewert festzuhalten, wenn die zu testende Methode vom Testprogramm aufgerufen wird. Das geht folgendermaßen:
string caseid, input, method, result;
int actual, expected;
Console.WriteLine("caseID  input method  expected  case result");
Console.WriteLine("===========================================");
Jetzt durchläuft die Haupttestschleife immer wieder jede Zeile des DataTable-Objekts, wie im Folgenden gezeigt:
for (int row = 0; row < dt.Rows.Count; ++row)
Führen Sie innerhalb der Haupttestschleife zunächst eine rudimentäre Prüfung durch, ob es sich wirklich um einen gültigen Testfall handelt. Rufen Sie dann jede Spalte der vorliegenden Zeile der DataTable auf, und speichern Sie diese unter Variablen mit aussagekräftigeren Namen, die Sie außerhalb der Schleife festsetzen:
object o = dt.Rows[row]["caseid"];
if (o == null) break;
caseid = (string)dt.Rows[row]["caseid"];
input = (string)dt.Rows[row]["input"];
method = (string)dt.Rows[row]["method"];
expected = int.Parse( (string)(dt.Rows[row]["expected"]) );
Beachten Sie, dass an dieser Stelle die Typenkonversionen erfolgen. Denken Sie daran, dass anfänglich alle Testfalldaten vom Typ „Text“ in der Excel-Tabelle und alle Daten vom Typ „String“ in das DataTable-Objekt gespeichert wurden. Jetzt können Sie die zu testende Methode aufrufen und den tatsächlichen Wert abrufen:
CribbageLib.Hand h = new Hand(new Card(input.Substring(0, 2)),
                              new Card(input.Substring(2, 2)),
                              new Card(input.Substring(4, 2)),
                              new Card(input.Substring(6, 2)),
                              new Card(input.Substring(8, 2)));

if (method == "ValueOf15s") actual = h.ValueOf15s;
else if (method == "ValueOfPairs") actual = h.ValueOfPairs;
else throw new Exception("Unknown method in test case data");
Nutzen Sie die String.Substring-Methode, um jedes Zeichenpaar wie etwa 7c, das ein Kartenobjekt darstellt, zu analysieren. Das erste Ganzzahl-Argument zur Bildung der untergeordneten Zeichenfolge ist ein nullbasierter Indexwert für die Stelle der Zeichenkette, wo das Extrahieren der untergeordneten Zeichenfolge beginnen soll. Das zweite Ganzzahl-Argument ist die Anzahl der zu extrahierenden Zeichen (und nicht der End-Index, wie Sie vielleicht gedacht haben). Schalten Sie auf den Wert der Methode „variable“ um, und rufen Sie die zu testende Methode auf, sodass der tatsächliche Rückgabewert erfasst wird. Um schließlich die Haupttestschleife zu beenden, stellen Sie Datum und Uhrzeit Ihrer Testfalldurchführung fest, stellen Sie das Testergebnis fest, erstellen Sie eine INSERT-Zeichenkette, geben Sie Ihr Ergebnis an die Konsole aus, und fügen Sie es in das Excel-Ergebnisarbeitsblatt ein.
DateTime whenRun = DateTime.Now;
result = (actual == expected) ? "Pass" : "FAIL";
          
Console.WriteLine(caseid + "   " + h.ToString() + " " +
                  method.PadRight(15, ' ') +
                  expected.ToString().PadRight(8, ' ') + result);
string insert = "INSERT INTO tblResults (caseID, Result, WhenRun)
                 values ('" + caseid + "', '" + result +
                 "', '" + whenRun + "')";
insertCmd.CommandText = insert;
insertCmd.ExecuteNonQuery();
Mit der PadRight-Methode können Sie das Ergebnis in Spalten darstellen – das ist ein alter Trick. Die INSERT-Anweisung ist wegen der eingebetteten einfachen Anführungszeichen, Kommata und Klammerzeichen etwas unangenehm; hierbei müssen Sie einfach vorsichtig sein. Wenden Sie beim Aufruf des INSERT-Befehls die ExecuteNonQuery-Methode an, um den Einfügungsvorgang durchzuführen.

Zusammenfassung
Wie bereits erwähnt, ist vereinfachte Testautomatisierung eine Ergänzung anderer Testautomatisierungsverfahren und nicht deren Ersatz. Wenn Sie sich in einem Szenario befinden, wo vereinfachte Automatisierung passend ist, stellt Excel eine hervorragende Wahl für die Speicherung von Testdaten dar. Die zwei Hauptalternativen für diese Speicherung sind einfache Textdateien und XML-Dokumente. Textdateien sind besonders einfach, haben jedoch im Vergleich zur Speicherung in Excel den entscheidenden Nachteil, dass falsche Steuersymbole und Whitespace-Zeichen schwer zu entdecken sind. Andererseits können XML-Dokumente für die Speicherung bei vereinfachter Testautomatisierung übertrieben sein. Die hierarchische Struktur von XML macht das Lesen und Schreiben der Daten in gewisser Weise schwieriger als das Lesen und Schreiben von in Excel gespeicherten Daten.
Darüber hinaus weist Excel einige praktische Vorteile auf, die bei dieser Art von Szenario nützlich sind. Zunächst einmal können Sie bei der Nutzung von Excel zur Speicherung von Testfalldaten die Strategie "Testfalldaten-Eintrag öffnen" anwenden. Dadurch können Sie die Excel-Datei in einen öffentlichen Bereich stellen und jedem Angehörigen Ihres Teams das Hinzufügen von Testfällen ermöglichen. Vor ein paar Jahren schrieb ich eine Poker-Bibliothek. Ich fand einen alten schrottreifen Computer, erstellte darauf eine Excel-Tabellenkalkulation für Testfalldaten, platzierte neben dem Computer ein Kartendeck und ermutigte alle, Testfälle einzugeben. Das war sehr erfolgreich, und das Verfahren deckte einige kritische Fehler auf. Da die meisten Menschen bequem mit Excel umgehen können, werden Sie bei dieser Art eines offenen Projekts wahrscheinlich eine höhere Beteiligung erreichen, als wenn Sie eine andere Datenspeicherung wählen. Die zweite bemerkenswerte Tatsache bezüglich Excel besteht darin, dass Sie über eine integrierte Möglichkeit verfügen, unter Nutzung der vielen mathematischen Funktionen einige Ergebnisanalysen von vereinfachten Tests durchzuführen, wenn Sie Ihre Ergebnisse in einem Arbeitsblatt speichern.
Das neue Microsoft Office 2007-System eröffnet Ihnen noch bessere Möglichkeiten, Excel zur Speicherung von Testdaten zu nutzen. Die neuen Office XML-Formate für Excel, Word und PowerPoint® bringen mit Sicherheit für die Softwareentwicklung und -prüfung mehrere Verbesserungen bei der Programminteroperabilität. Da das neue Excel-Dateiformat .xlsx auf XML basiert, bringt es verbesserte Möglichkeiten der Dateiverwaltung und eine verbesserte Möglichkeit der Reparatur beschädigter Dateien mit sich. Und da die Office XML-Formate die Komprimierungstechnologie ZIP benutzen, werden Testdaten-Dateien erheblich kleiner.

Schicken Sie Ihre Fragen und Kommentare in englischer Sprache an Dr. James McCaffrey unter testrun@microsoft.com.


Dr. James McCaffrey arbeitet für Volt Information Sciences Inc., wo er technische Schulungen für Softwareentwickler von Microsoft organisiert. Er hat an mehreren Microsoft-Produkten gearbeitet, unter anderem an Internet Explorer und MSN Search. Sie erreichen James unter jmccaffrey@volt.com oder v-jammc@microsoft.com.

Page view tracker