Classe basata sui dati
Assicurarsi di avere familiarità con l'esecuzione di base di TAEF e sapere come creare test usando questa sezione prima di procedere con questa sezione. È anche possibile esaminare l'esempio di test basato sui dati semplice. In questa sezione si eseguirà una classe di test basata su dati basata su una tabella basata su dati, ma lo stesso approccio si applica ai test basati suWMI o basati su PICT .
Quando usare una classe basata sui dati?
Esistono volte in cui più test possono dipendere dagli stessi dati di input. Quando si testano LE API, è possibile eseguire più test API con gli stessi dati per ottenere una visualizzazione coerente del comportamento dell'API. Quando si eseguono test a livello di scenario, è possibile assicurarsi che tutti i passaggi nello scenario vengano testati con gli stessi dati. In questi casi, è utile specificare i dati di test a livello di classe.
Creazione di una classe basata sui dati
Si specifica che una determinata classe è basata sui dati in modo analogo a come si specifica che un determinato test è basato sui dati. Si applicano i metadati di DataSource a livello di classe. Il valore identifica l'origine dati specifica di interesse. Nell'esempio seguente viene illustrato come specificare queste proprietà per le classi basate sui dati:
Codice nativo
1 class 2 {
2 BEGIN_TEST_CLASS(DataDrivenClassExample)
3 TEST_CLASS_PROPERTY(L"DataSource", L"Table:DataDrivenClassExample.xml#ClassTable")
4 END_TEST_CLASS()
5
6 TEST_METHOD(Test1);
7 {
8 int size;
9 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"size", size)</span>))
10 {
11 VERIFY_ARE_NOT_EQUAL(size, 0);
12 Log::Comment(String().Format(L"Size retrieved was %d", size));
13 }
14
15 String color;
16 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"color", color)</span>))
17 {
18 Log::Comment(L"Color retrieved was " + color);
19 }
20 }
21 TEST_METHOD(Test2);
22 {
23 int size;
24 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"size", size)</span>))
25 {
26 VERIFY_ARE_NOT_EQUAL(size, 0);
27 Log::Comment(String().Format(L"Size retrieved was %d", size));
28 }
29
30 String color;
31 if (SUCCEEDED(<span class="style2">TestData::TryGetValue(L"color", color)</span>))
32 {
33 Log::Comment(L"Color retrieved was " + color);
34 }
35 }
36 };
Codice gestito
1 [TestClass]
2 public class CSharpDataDrivenClassExample
3 {
4 [ClassInitialize]
5 [DataSource("Table:CSharpDataDrivenClassExample.xml#ClassTable")]
6 public static void MyClassInitialize(Object testContext)
7 {
8 }
9
10 [TestMethod]
11 public void Test1()
12 {
13 int size = (int)m_testContext.DataRow["Size"];
14 Verify.AreNotEqual(size, 0);
15 Log.Comment("Size is " + size.ToString());
16
18 Log.Comment("Color is " + m_testContext.DataRow["Color"]);
19 }
20
21 [TestMethod]
22 public void Test2()
23 {
24 int size = (int)m_testContext.DataRow["Size"];
25 Verify.AreNotEqual(size, 0);
26 Log.Comment("Size is " + size.ToString());
27
28 Log.Comment("Color is " + m_testContext.DataRow["Color"]);
29 }
30
31 public TestContext TestContext
32 {
33 get { return m_testContext; }
34 set { m_testContext = value; }
35 }
36
37 private TestContext m_testContext;
38 }
In questi esempi, la riga 3 nell'esempio di codice nativo e la riga 5 nell'esempio di codice gestito sono i modi consigliati per specificare l'origine dati per una classe di test basata sui dati in TAEF.
Nell'esempio di codice gestito precedente, le righe 13, 18, 24 e 28 mostrano come i dati vengono resi disponibili ai metodi di test per il codice gestito.
Nell'esempio di codice seguente, le righe 4, 11, 20 e 27 mostrano come i dati vengono resi disponibili ai metodi di test per il codice nativo. Si noti che i dati definiti nella tabella basata sui dati (righe) sono disponibili per i metodi di test nella classe (Test1 e Test2) esattamente come si farebbe per un test basato sui dati.
Creare il file XML DataSource per una classe basata sui dati esattamente come si farebbe per un test basato sui dati. Gli esempi seguenti illustrano i file XML per le classi native e gestite.
Nativo
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="ClassTable">
4 <ParameterTypes>
5 <ParameterType Name="Size">int</ParameterType>
6 </ParameterTypes>
7 <Row>
8 <Parameter Name="Size">4</Parameter>
9 <Parameter Name="Color">White</Parameter>
10 </Row>
11 <Row>
12 <Parameter Name="Size">10</Parameter>
13 <Parameter Name="Color">Black</Parameter>
14 </Row>
15 <Row>
16 <Parameter Name="Size">9</Parameter>
17 <Parameter Name="Color">Orange</Parameter>
18 </Row>
19 <Row>
20 <Parameter Name="Size">9</Parameter>
21 <Parameter Name="Color">Blue</Parameter>
22 </Row>
23 </Table>
24</Data>
Gestito
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="ClassTable">
4 <ParameterTypes>
5 <ParameterType Name="Size">Int32</ParameterType>
6 <ParameterType Name="Color">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">10</Parameter>
14 <Parameter Name="Color">Black</Parameter>
15 </Row>
16 <Row>
17 <Parameter Name="Size">9</Parameter>
18 <Parameter Name="Color">Orange</Parameter>
19 </Row>
20 <Row>
21 <Parameter Name="Size">9</Parameter>
22 <Parameter Name="Color">Blue</Parameter>
23 </Row>
24 </Table>
25</Data>
Dietro le quinte O cosa aspettarsi?
Per impostazione predefinita, quando si creano test in TAEF, l'ordine di esecuzione all'interno di una classe è uguale all'ordine in cui sono stati codificati i metodi di test nella classe. Pertanto, negli esempi precedenti , Test1 verrà sempre eseguito prima di Test2. Poiché la classe contenente Test1 e Test2 è una classe basata sui dati, tutti i metodi di classe verranno eseguiti una volta per ogni RIGA di dati definita in DataSource. In altre parole, Test1 e Test2 vengono eseguiti per row #0. Questi metodi vengono quindi eseguiti nello stesso ordine per Row #1 e così via fino a quando TAEF esegue tutte le righe.
Esecuzione di test in una classe basata su dati
Se si eseguono i file binari di test di esempio con l'opzione di comando /list , l'ordine di esecuzione della sezione precedente diventa chiaro.
Nativo
TE.exe Examples\CPP.AdvancedDataDriven.Examples.dll /name:*class* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CPP.AdvancedDataDriven.Examples.dll
WEX::TestExecution::Examples::DataDrivenClassExample#0
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#1
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#2
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#3
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test2
Gestito
TE.exe Examples\CSharp.AdvancedDataDriven.Examples.dll /name:*class* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CSharp.AdvancedDataDriven.Examples.dll
WEX.Examples.CSharpDataDrivenClassExample#0
WEX.Examples.CSharpDataDrivenClassExample#0.Test1
WEX.Examples.CSharpDataDrivenClassExample#0.Test2
WEX.Examples.CSharpDataDrivenClassExample#1
WEX.Examples.CSharpDataDrivenClassExample#1.Test1
WEX.Examples.CSharpDataDrivenClassExample#1.Test2
WEX.Examples.CSharpDataDrivenClassExample#2
WEX.Examples.CSharpDataDrivenClassExample#2.Test1
WEX.Examples.CSharpDataDrivenClassExample#2.Test2
WEX.Examples.CSharpDataDrivenClassExample#3
WEX.Examples.CSharpDataDrivenClassExample#3.Test1
WEX.Examples.CSharpDataDrivenClassExample#3.Test2
Si noti che gli indici negli esempi precedenti sono simili ai test basati sui dati. Ogni riga della classe guidata dai dati viene identificata da un indice. Proprio come nei test basati sui dati, è possibile scegliere di assegnare una riga a un nome più significativo specificando i metadati a livello di riga nel file XML e stampando tale nome anziché l'indice quando si elencano o eseguono i test.
Analogamente, si usa l'opzione /listproperties per verificare che i dati siano effettivamente specificati e disponibili a livello di classe.
Nativo
F:\ Examples\CPP.AdvancedDataDriven.Examples.dll
WEX::TestExecution::Examples::DataDrivenClassExample#0
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = White
Data[Size] = 4
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#0::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#1
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = Black
Data[Size] = 10
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#1::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#2
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = Orange
Data[Size] = 9
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#2::Test2
WEX::TestExecution::Examples::DataDrivenClassExample#3
Property[DataSource] = Table:DataDrivenClassExample.xml#ClassTable
Data[Color] = Blue
Data[Size] = 9
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test1
WEX::TestExecution::Examples::DataDrivenClassExample#3::Test2
Gestito
F:\ Examples\CSharp.AdvancedDataDriven.Examples.dll
WEX.Examples.CSharpDataDrivenClassExample#0
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = White
Data[Size] = 4
WEX.Examples.CSharpDataDrivenClassExample#0.Test1
WEX.Examples.CSharpDataDrivenClassExample#0.Test2
WEX.Examples.CSharpDataDrivenClassExample#1
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = Black
Data[Size] = 10
WEX.Examples.CSharpDataDrivenClassExample#1.Test1
WEX.Examples.CSharpDataDrivenClassExample#1.Test2
WEX.Examples.CSharpDataDrivenClassExample#2
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = Orange
Data[Size] = 9
WEX.Examples.CSharpDataDrivenClassExample#2.Test1
WEX.Examples.CSharpDataDrivenClassExample#2.Test2
WEX.Examples.CSharpDataDrivenClassExample#3
Setup: MyClassInitialize
Property[DataSource] = Table:CSharpDataDrivenClassExample.xml#ClassTable
Data[Color] = Blue
Data[Size] = 9
WEX.Examples.CSharpDataDrivenClassExample#3.Test1
WEX.Examples.CSharpDataDrivenClassExample#3.Test2
È possibile applicare tutte le regole di esecuzione alla classe basata sui dati. È possibile basare la query di selezione su qualsiasi elemento che è possibile elencare nell'opzione /listproperties .
Test basati sui dati in una classe basata sui dati
Non si è limitati in alcun modo ai test basati sui dati all'interno di una classe basata sui dati. Questo approccio può essere utile durante la scrittura di test API. È possibile mantenere i dati comuni per tutti i test in una classe a livello di classe DataSource. Specificare i dati specifici del metodo di test nei metadati di DataSource per il metodo contrassegnato come basato sui dati.
NOTA: in questi casi l'ordine di esecuzione è un po' più coinvolto.
Negli esempi seguenti viene illustrato il rendering dei file binari di esempio precedenti con l'opzione /list command.
Nativo
TE.exe Examples\CPP.AdvancedDataDriven.Examples.dll /name:*nested* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CPP.AdvancedDataDriven.Examples.dll
WEX::TestExecution::Examples::NestedDataDrivenExample#0
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#0::Test2#3
WEX::TestExecution::Examples::NestedDataDrivenExample#1
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#1::Test2#3
WEX::TestExecution::Examples::NestedDataDrivenExample#2
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#2::Test2#3
WEX::TestExecution::Examples::NestedDataDrivenExample#3
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test1
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#0
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#1
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#2
WEX::TestExecution::Examples::NestedDataDrivenExample#3::Test2#3
Gestito
TE.exe Examples\CSharp.AdvancedDataDriven.Examples.dll /name:*nested* /list
Test Authoring and Execution Framework v2.9.3k for x86
F:\ Examples\CSharp.AdvancedDataDriven.Examples.dll
WEX.Examples.CSharpDataDrivenNestedExample#0
WEX.Examples.CSharpDataDrivenNestedExample#0.Test1
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#0.Test2#3
WEX.Examples.CSharpDataDrivenNestedExample#1
WEX.Examples.CSharpDataDrivenNestedExample#1.Test1
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#1.Test2#3
WEX.Examples.CSharpDataDrivenNestedExample#2
WEX.Examples.CSharpDataDrivenNestedExample#2.Test1
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#2.Test2#3
WEX.Examples.CSharpDataDrivenNestedExample#3
WEX.Examples.CSharpDataDrivenNestedExample#3.Test1
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#0
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#1
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#2
WEX.Examples.CSharpDataDrivenNestedExample#3.Test2#3
NOTA: L'unica restrizione in questo caso è che le tabelle per i due esempi non possono trovarsi nello stesso file DataSource. In altre parole, DataSource per la classe basata sui dati e il metodo di test basato sui dati che contiene deve essere diverso.
Si noti che il metodo Test2 negli esempi è un test basato sui dati all'interno di una classe basata sui dati. Ad esempio, nella riga WEX. Esempi.CSharpDataDrivenNestedExample#3.Test2#0, #3 è l'indice per la classe e #0 è l'indice per il test guidato dai dati all'interno di tale classe. Test2 può accedere a entrambe le tabelle: i dati nella riga dell'istanza della classe a cui appartiene e i dati nella riga corrente per la propria tabella DataSource . In altre parole, i dati a livello di classe e i dati a livello di metodo di test vengono aggregati insieme e sono disponibili durante l'esecuzione del metodo di test.
Cosa accade nel caso di dati in conflitto: se lo stesso nome dei dati viene specificato sia a livello di classe che a livello di metodo? TAEF elabora questa condizione nello stesso modo in cui elabora le proprietà dei metadati. I dati specificati in una riga a livello di metodo sostituiscono i dati specificati in una riga a livello di classe.
Si consideri ad esempio il caso in cui si ha un parametro denominato Size specificato sia a livello di classe che a livello di metodo di test. A livello di classe, le dimensioni sono definite come tipo String Array , ma a livello di metodo di test, è definito come int. In questo caso, il tipo int esegue l'override del tipo String Array a livello di metodo di test, nonché ai metodi Setup e Teardown per il test. Tuttavia, a livello di classe, i metodi Setup e Teardown hanno il tipo di dati String Array.
Se nel codice sono presenti dati in conflitto, TAEF mostra un avviso durante l'esecuzione ed elenca le proprietà, ma i dati in conflitto non generano alcun errore.