Array-Unterstützung für datengesteuerte Tests – Beispiel
In diesem Abschnitt werden einige fortgeschrittene Funktionen des datengesteuerten Testens anhand eines Beispiels erläutert. Wenn Sie noch mit den Grundlagen beschäftigt sind, sollten Sie mit einem Einfachen datengesteuerten Beispiel beginnen.
Beispiele, auf die verwiesen wird:
ArraySupportDataDrivenExample
CSharpDataDrivenArraySupportExample
In den vorangegangenen Abschnitten wurden bereits die Grundlagen der Erstellung und Ausführung von datengesteuerten Tests behandelt. In der folgenden Liste wird die Bedeutung von Arrays im Sinne von TAEF Data Driven Testing erläutert:
- Arrays sind Elemente mit variabler Länge und homogenem Typ, die wie ein einzelner Parameter behandelt werden.
- Um einen Array-Typ anzugeben, müssen Sie den Typ des Parameters im Block ParameterTypes explizit angeben und ein Attribut Array="true" hinzufügen.
Die unterstützten Parametertypen sind in Parametertypen in Tabellendatenquellen aufgeführt.
Wenn ein anderer Datentyp angegeben wird, gibt der Test eine Warnung aus und betrachtet ihn als Zeichenfolge. Im Falle von Arrays würde der Datentyp als vom Typ String[] betrachtet werden.
Das folgende Beispiel zeigt, wie Sie angeben, dass der Parameter ein Array eines der Grundtypen ist. Es ist wichtig zu beachten, dass bei Arrays keine Standardtypen zugelassen sind – Sie müssen den Typ explizit angeben und das Attribut Array festlegen, damit der Parameter wahr ist.
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="ArraySupportTable">
4 <ParameterTypes>
5 <ParameterType Name="Size" Array="true">int</ParameterType>
6 <ParameterType Name="Color" Array="true">String</ParameterType>
7 </ParameterTypes>
8 <Row>
9 <Parameter Name="Size">4</Parameter>
10 <Parameter Name="Color">White</Parameter>
11 </Row>
12 <Row>
13 <Parameter Name="Size">
14 <Value>4</Value>
15 <Value>6</Value>
16 <Value>8</Value>
17 </Parameter>
18 <Parameter Name="Color">
19 <Value>Red</Value>
20 <Value>Green</Value>
21 <Value>Blue</Value>
22 </Parameter>
23 </Row>
24 <Row>
25 <Parameter Name="Size">
26 <Value>9</Value>
27 <Value>12</Value>
28 <Value>16</Value>
29 </Parameter>
30 <Parameter Name="Color">Orange</Parameter>
31 </Row>
32 <Row>
33 <Parameter Name="Size">9</Parameter>
34 <Parameter Name="Color">
35 <Value>White</Value>
36 <Value>Black</Value>
37 </Parameter>
38 </Row>
39 </Table>
40 </Data>
Sehen Sie sich die Value-Tags und die Array-Attribute im obigen Beispiel an. Zunächst müssen Sie explizit den Typ für die beiden Parameter Size und Color angeben und festlegen, dass diese Parameter Arrays sind, indem Sie das Attribut Array auf true festlegen. Dann geben Sie die Werte in <Value>...</Value>-Tags an. Sie können so viele <Value>-Tags verwenden, wie Sie benötigen, um eine beliebige Anzahl von Werten innerhalb des Arrays für einen bestimmten Parameter der Zeile anzugeben.
Beachten Sie die Zeilen 9, 10, 30 und 33 in den obigen XML-Beispielen. Diese Einträge sind einwertige Array-Elemente. Mit anderen Worten: Sie können einwertige Array-Elemente direkt im <Parameter>-Tag ohne ein zusätzliches <Value>-Tag angeben. Außerdem wird der Parameter in der Zeile, auch wenn er nur einen Wert hat, immer noch als Array mit einem Element behandelt und kann nicht anders abgerufen werden.
Werfen wir nun einen Blick auf die Abruf-APIs.
Nativer Abruf
Array-Elemente können in nativem Code abgerufen werden, indem Sie die WEX::TestExecution::TestDataArray<>-Vorlagenklasse verwenden. Einzelheiten finden Sie in der veröffentlichten Header-Datei TestData.h. Die Klasse TestDataArray verwaltet die Lebensdauer der Array-Elemente und bietet nützliche APIs zum Abrufen bestimmter Werte innerhalb des Arrays:
1 namespace WEX { namespace TestExecution
2 {
3 template <typename T>
4 class TECOMMON_API TestDataArray sealed
5 {
6 ...
7 public:
8 TestDataArray();
9 ~TestDataArray();
10 const size_t GetSize() const;
11 T& operator[](size_t index);
12
13 private:
14 ...
15 };
16 } /* namespace TestExecution */ } /* namespace WEX */
Sie können die Länge des Arrays durch den Aufruf von GetSize erhalten und ein bestimmtes Element durch den Operator [] abrufen.
Das nächste Beispiel zeigt, wie Sie diese Funktionen im Code verwenden können. Betrachten Sie die cpp-Datei im nativen Beispiel:
1 TestDataArray<int> sizes;
2 if (SUCCEEDED(TestData::TryGetValue(L"size", sizes)))
3 {
4 size_t count = sizes.GetSize();
5 for (size_t i = 0; i < count; ++i)
6 {
7 Log::Comment(String().Format(L"Size[%d] retrieved was %d", i, sizes[i]));
8 }
9 }
10
11 TestDataArray<String> colors;
12 if (SUCCEEDED(TestData::TryGetValue(L"color", colors)))
13 {
14 size_t count = colors.GetSize();
15 for (size_t i = 0; i < count; ++i)
16 {
17 Log::Comment(String().Format(L"Color[%d] retrieved was ", i) + colors[i]);
18 }
19 }
Zunächst definieren Sie ein lokales TestDataArray vom Typ Array. In diesem Fall ist sizes ein Array vom Typ int und colors ist ein Array vom Typ WEX::Common::String. Die API zum Abrufen eines Arrays ist ähnlich wie die zum Abrufen einer beliebigen Variablen. Sie rufen TestData::TryGetValue auf, bitten es, den Parameter size abzurufen und den Wert in die lokale Variable sizes zu setzen.
Beachten Sie, dass der Versuch, einen nicht in einem Array angegebenen Parameter in ein Array zu übertragen, einen Fehler verursacht und den Test nicht bestehen lässt. Ebenso führt der Versuch, ein Array in eine Nicht-Array-Variable abzurufen, zu einem Fehler, selbst wenn das Array nur ein Element hat.
Wenn ein Array-Parameter in der XML-Zeile überhaupt nicht angegeben ist, schlägt der Versuch, den Parameter abzurufen, fehl. Wenn eine Zeile zum Beispiel so aussehen würde:
<Row>
<Parameter Name="Color">
<Value>White</Value>
<Value>Black</Value>
</Parameter>
</Row>
Beachten Sie, dass der Parameter Size, der ein Array ist, in der Zeile nicht angegeben ist. Wenn Sie versuchen, Size aus dem Code abzurufen, würde der API-Aufruf einen fehlgeschlagenen Rückgabecode zurückgeben. Sie könnten dies nutzen, um einen Standard-Array-Wert zu definieren.
Andererseits können Sie ein leeres Array angeben, indem Sie ein leeres Parameter-Tag für Size wie folgt angeben:
<Row>
<Parameter Name="Size"></Parameter>
<Parameter Name="Color">
<Value>White</Value>
<Value>Black</Value>
</Parameter>
</Row>
In diesem Fall wäre der Versuch, Size abzurufen, erfolgreich, aber die Array-Größe wäre 0.
Verwalteter Abruf
Der verwaltete Abruf ist fast derselbe wie zuvor – Sie müssen nur darauf achten, dass die Werte in eine lokale Variable des entsprechenden Array-Typs abgerufen werden. Betrachten Sie das folgende verwaltete Beispiel:
1 Int32[] sizes = m_testContext.DataRow["Size"] as Int32[];
2 foreach (int size in sizes)
3 {
4 Verify.AreNotEqual(size, 0);
5 Console.WriteLine("Size is " + size.ToString());
6 }
7
8 String[] colors = m_testContext.DataRow["Color"] as String[];
9 foreach (String color in colors)
10 {
11 Console.WriteLine("Color is " + color);
12 }
Ähnlich wie beim nativen Abruf, wenn ein Array-Parameter in der XML-Zeile überhaupt nicht angegeben ist, gibt der Versuch, den Parameter abzurufen, ein Objekt vom Typ System.DBNull zurück. Wenn eine Zeile zum Beispiel so aussehen würde:
<Row>
<Parameter Name="Color">
<Value>White</Value>
<Value>Black</Value>
</Parameter>
</Row>
Beachten Sie, dass der Parameter Size, der ein Array ist, in der Zeile nicht angegeben ist. Wenn Sie versuchen, Size aus dem Code abzurufen, würde der API-Aufruf ein Objekt vom Typ DBNull zurückgeben. Wenn Sie solche Werte in Ihrer Tabelle haben, sollten Sie sie zunächst aus dem Kontext in ein Objekt abrufen und dann geeignete Schritte unternehmen, nachdem Sie den Typ des Objekts mit typeof(System.DBNull) oder dem Typ, den Sie erwarten, verglichen haben.
Andererseits können Sie ein leeres Array angeben, indem Sie ein leeres Parameter-Tag für Size wie folgt angeben:
<Row>
<Parameter Name="Size"></Parameter>
<Parameter Name="Color">
<Value>White</Value>
<Value>Black</Value>
</Parameter>
</Row>
In diesem Fall gibt der Versuch, size abzurufen, erfolgreich ein leeres Array vom Typ System.Int32[] zurück.
Ausführung
Die Ausführung von datengesteuerten Tests, die Arrays unterstützen, unterscheidet sich nicht von der Ausführung jedes anderen datengesteuerten Tests. Der einzige wesentliche Unterschied besteht darin, dass die Semantik des Auswahlkriteriums sich im Fall von Array-Datenparametern dahingehend ändert, dass es „enthält“ und nicht „gleich“ bedeutet.
Um zu sehen, was das bedeutet, nehmen Sie an, dass Sie alle datengesteuerten Tests auswählen möchten, bei denen das Array Color den Wert White enthält. Führen Sie dazu Folgendes aus:
TE.exe Examples\CSharp.DataDriven.Example.dll /select:"@Name='*Array* And @Data:Color='White'"
TE.exe Examples\CPP.DataDriven.Example.dll /select:"@Name='*Array* And @Data:Color='White'"
Dieser Befehl führt die datengesteuerten Tests mit Index #0 und #3 in beiden oben genannten Fällen aus.
Sie können komplexere Abfragen erstellen, die z. B. nur die Tests auswählen, in denen das Array Color den Wert White und das Array Color den Wert Black enthält, wodurch nur die datengesteuerten Tests mit dem Index #3 ausgewählt würden. Versuchen Sie als Aufgabe, diese Abfrage selbst zu schreiben und auszuführen.