Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Zorg ervoor dat u bekend bent met de basisuitvoering van TAEF- en weet hoe u Ontwerptests gebruiken, voordat u doorgaat met deze sectie.
Nu u eenvoudige testautomatisering hebt geschreven en met TAEF werkt, kunt u zich concentreren op scenario's waarin dezelfde testcode kan worden gebruikt om te werken aan verschillende gegevenssets. Voor dit doel biedt TAEF een benadering op basis van tabellen voor gegevensgestuurde tests. Laten we eens kijken naar een eenvoudig voorbeeld om te begrijpen hoe u een gegevensgestuurde test kunt ontwerpen.
Bekijk een eenvoudig niet-gegevensgestuurd voorbeeld waarin u de grootte en het thema op de console afdrukt. In deze oefening converteert u deze test naar een gegevensgestuurde test.
1 namespace WEX { namespace TestExecution { namespace Examples
2 {
3 void DataDrivenTests::FirstTable()
4 {
5 int size = 12;
6 Log::Comment(String().Format(L"Size retrieved was %d", size));
7 }
8
9 void DataDrivenTests::SecondTable()
10 {
11 String theme = "Aero";
12 Log::Comment(L"Theme supplied as " + theme);
13 }
14 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */
de gegevens definiëren
U wilt nu dat de bovenstaande functie werkt voor een set grootten en thema's. Met andere woorden, u wilt gegevenswaarden voor varianten die door onze functie gebruikt kunnen worden. Om dit te doen, definieert u twee tabellen in een XML-bestand DataDrivenTests.xml:
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id ="Table1">
4 <ParameterTypes>
5 <ParameterType Name="Size">Int32</ParameterType>
6 <ParameterType Name="Color">String</ParameterType>
7 <ParameterType Name="Transparency">Boolean</ParameterType>
8 </ParameterTypes>
9 <Row Priority="1" Owner="C2">
10 <Parameter Name="Size">12</Parameter>
11 <Parameter Name="Color">Blue</Parameter>
12 <Parameter Name="Transparency">True</Parameter>
13 </Row>
14 <Row Priority="2" Owner="wex">
15 <Parameter Name="Size">4</Parameter>
16 <Parameter Name="Color">White</Parameter>
17 <Parameter Name="Transparency">False</Parameter>
18 </Row>
19 <Row Owner="C2">
20 <Parameter Name="Size">9</Parameter>
21 <Parameter Name="Color">Black</Parameter>
22 <Parameter Name="Transparency">True</Parameter>
23 </Row>
24 </Table>
25 <Table id ="Table2">
26 <Row Description="ButtonTest" Owner="C2" Priority="1">
27 <Parameter Name="Control">Button</Parameter>
28 <Parameter Name="Theme">Aero</Parameter>
29 </Row>
30 <Row Description="ComboBoxTest" Priority="2">
31 <Parameter Name="Control">ComboBox</Parameter>
32 <Parameter Name="Theme">Classic</Parameter>
33 </Row>
34 <Row Description="ListviewTest" Owner="wex">
35 <Parameter Name="Control">Listview</Parameter>
36 <Parameter Name="Theme">AeroBasic</Parameter>
37 </Row>
38 </Table>
39 </Data>
U hebt nu twee tabellen gedefinieerd: 'Table1' en 'Table2'. U kunt tabellen definiëren voor verschillende testmethoden in hetzelfde XML-bestand.
Observeer dat u in Tabel1 de ParameterTypes vooraf hebt gedefinieerd en 'Grootte' als een geheel getal hebt gekozen. De sectie ParameterTypes is optioneel. Als er geen informatie over het parametertype wordt opgegeven, wordt deze standaard opgeslagen als een tekenreeks. Dit is het geval voor alle parameters in Tabel2.
Elke rij die in een tabel is gedefinieerd, is een set gegevenswaarden (parameterwaarden) die u wilt accepteren door de testfunctie. Regels 9, 14 en 19 definiëren drie gegevenssets die door de functie FirstTable worden geaccepteerd. Op dezelfde manier definieert regel 26, 30 en 34 de gegevenssets voor SecondTable.
Let op regels 9, 14, 19, 26, 30 en 34 in het bovenstaande voorbeeld: u kunt metagegevens definiëren die specifiek zijn voor de rij. Er is nu een manier om metagegevensgegevens te wijzigen met gegevenssets voor dezelfde functie. De prioriteit voor de eerste gegevensset (regel 9) is 1, prioriteit voor de tweede gegevensset (regel 14) is 2 en de derde set gegevens (regel 19) wordt standaard ingesteld op de prioriteit van de functie. Alle rijen nemen de metagegevens over van de functie waarmee de tabel is gekoppeld. Als dezelfde metagegevens opnieuw op rijniveau worden opgegeven, worden de metagegevenswaarden overschreven die zijn gedefinieerd op functieniveau.
OPMERKING: de definitie van het XML-bestandsschema is hetzelfde voor systeemeigen en beheerde code, met uitzondering van typedefinities die worden ondersteund. Zie het eerste gedeelte van de sectie Beheerde gegevensgestuurde test hieronder voor een ander voorbeeld van het definiëren van de gegevens. Ga door met systeemeigen gegevensgestuurde test om inzicht te hebben in typen die zijn toegestaan in systeemeigen code.
Systeemeigen gegevensgestuurde test
Nu de gegevenssets zijn gedefinieerd en gereed zijn voor verbruik, hebt u nu een manier nodig om de testfunctie te kwalificeren als een gegevensgestuurde test en deze te koppelen aan de tabel waarmee de gegevensset wordt gedefinieerd. Dit wordt gedaan door middel van extra metagegevens tijdens het ontwerpen van de test:
1 namespace WEX { namespace TestExecution { namespace Examples
2 {
3 class DataDrivenTests
4 {
5 TEST_CLASS(DataDrivenTests);
6
7 BEGIN_TEST_METHOD(SecondTable)
8 TEST_METHOD_PROPERTY(L"DataSource", L"Table:DataDrivenTests.xml#Table2")
9 TEST_METHOD_PROPERTY(L"Priority", L"3")
10 END_TEST_METHOD()
11
12 BEGIN_TEST_METHOD(FirstTable)
13 TEST_METHOD_PROPERTY(L"Priority", L"4")
14 TEST_METHOD_PROPERTY(L"DataSource", L"Table:DataDrivenTests.xml#Table1")
15 END_TEST_METHOD()
16 };
17 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */
Als u de XML-tabel aan de test wilt koppelen, voegt u de metagegevens 'DataSource' toe aan de methode van de test. Via deze koppeling gebruikt TAEF de gegeven DataSource om de test uit te voeren. De waarde datasource heeft drie delen:
- 'Tabel:': hiermee wordt de gegevensbron geïdentificeerd als een XML-tabel.
- 'DataDrivenTests.xml' - dit is het bestand dat de XML-tabel bevat.
- '#Table2': na de delimeter '#' identificeert de waarde Tabel2 de specifieke tabel in het XML-document dat moet worden gebruikt. Een gegevensbron voor één XML-tabel kan meerdere tabellen bevatten. TAEF doorzoekt het XML-bestand voor een tabelelement met een id-kenmerk dat overeenkomt met de opgegeven waarde.
Mogelijk hebt u in het bovenstaande voorbeeld gezien dat 'SecondTable' is gedefinieerd voor 'FirstTable'. Dit betekent dat de functie SecondTable wordt uitgevoerd vóór de functie FirstTable, maar u hebt 'Table1' gedefinieerd, de tabel die overeenkomt met 'FirstTable', vóór 'Table2', de tabel die overeenkomt met 'SecondTable'. Dit is om te benadrukken dat de volgorde van de tabeldefinitie niet relevant is tijdens de detectie en uitvoering van de gegevensgestuurde tests.
Nu de toewijzing van de gegevensbron aan de testmethode is voltooid, kunt u nu het voorbeeld wijzigen om de gegevens op te halen uit de bron. Voordat u dit doet, bekijkt u het gepubliceerde headerbestand TestData.h. Het deel van belang is:
1 class TestData
2 {
3 public:
4 template <typename T>
5 static HRESULT __stdcall TryGetValue(_In_z_ const wchar_t* pszString, T& result)
6 {
7 return Private::TestData<T>::TryGetValue(pszString, result);
8 }
9 };
Regel 5 toont de API die moet worden aangeroepen om de gegevens in de functie op te halen. Bekijk de beschikbare parametertypen om op te halen.
Ok - alles ingesteld om ons voorbeeld opnieuw te schrijven:
1 namespace WEX { namespace TestExecution { namespace Examples
2 {
3 void DataDrivenTests::FirstTable()
4 {
5 Log::Comment(L"I am in first table");
6 int size;
7 if (SUCCEEDED(TestData::TryGetValue(L"size", size)))
8 {
9 VERIFY_ARE_NOT_EQUAL(size, 0);
10 Log::Comment(String().Format(L"Size retrieved was %d", size));
11 }
12 }
13
14 void DataDrivenTests::SecondTable()
15 {
16 Log::Comment(L"I am in second table.");
17 String theme;
18 if (SUCCEEDED(TestData::TryGetValue(L"theme", theme)))
19 {
20 Log::Comment(L"Theme supplied as " + theme);
21 }
22 }
23 } /* namespace Examples */ } /* namespace TestExecution */ } /* namespace WEX */
Regel 7 en 18 zijn de belangrijkste onderdelen die zijn gewijzigd om de test data-gedreven te maken. Geen grote verandering. Bekijk het uitvoeren van gegevensgestuurde tests om te begrijpen hoe u het meeste uit TAEF haalt tijdens het uitvoeren van gegevensgestuurde tests.
beheerde gegevensgestuurde test
Bekijk een voorbeeld waarin u de coördinaten van een rechthoek op de console wilt afdrukken. Begin met het definiëren van deze coördinaten als de gegevensset in een XML-bestand.
1 <?xml version="1.0"?>
2 <Data>
3 <Table Id="FirstTable">
4 <ParameterTypes>
5 <ParameterType Name="Left">Int32</ParameterType>
6 <ParameterType Name="Right">String</ParameterType>
7 <ParameterType Name="Top">Integer</ParameterType>
8 <ParameterType Name="Bottom">Int32</ParameterType>
9 </ParameterTypes>
10 <Row Priority="1" Owner="C2" Description="Zero rect">
11 <Parameter Name="Left">0</Parameter>
12 <Parameter Name="Right">0</Parameter>
13 <Parameter Name="Top">0</Parameter>
14 <Parameter Name="Bottom">0</Parameter>
15 </Row>
16 <Row Priority="2" Owner="wex" Description="normal rect">
17 <Parameter Name="Left">12</Parameter>
18 <Parameter Name="Right">25</Parameter>
19 <Parameter Name="Top">10</Parameter>
20 <Parameter Name="Bottom">50</Parameter>
21 </Row>
22 <Row Owner="C2" Description="invalid rect">
23 <Parameter Name="Left">30</Parameter>
24 <Parameter Name="Right">15</Parameter>
25 <Parameter Name="Top">40</Parameter>
26 <Parameter Name="Bottom">10</Parameter>
27 </Row>
28 </Table>
29 </Data>
Definieer de gegevensset in het bereik van een tabel, in dit geval FirstTable, die is gedefinieerd in regel 3 hierboven. U kunt tabellen definiëren voor verschillende testmethoden in hetzelfde XML-bestand.
U ziet dat FirstTable de ParameterTypes vooraf definieert en 'Left' als 'Int32' definieert. De sectie ParameterTypes is optioneel. Als er geen informatie over het parametertype wordt opgegeven, wordt deze standaard opgeslagen als een tekenreeks.
Bekijk de lijst met ondersteunde parametertypen.
Als er een ander gegevenstype is opgegeven, genereert de test een waarschuwing en beschouwt deze als een tekenreeks.
OPMERKING: de typetekenreeksen zijn niet hoofdlettergevoelig, maar moeten exact worden gespeld zoals hierboven wordt weergegeven.
Elke rij die in een tabel is gedefinieerd, is een set gegevenswaarden (parameterwaarden) die u wilt accepteren door de testfunctie. Regels 10, 16 en 22 definiëren drie gegevenssets die door onze functie worden gebruikt.
Let op regels 10, 16 en 22 in het bovenstaande voorbeeld: u kunt metagegevens definiëren die specifiek zijn voor rij. U hebt nu een manier om metagegevensgegevens te wijzigen met gegevenssets voor dezelfde functie. De prioriteit voor de eerste gegevensset (regel 10) is 1, prioriteit voor de tweede gegevensset (regel 16) is 2 en de derde set gegevens (regel 22) wordt standaard ingesteld op de prioriteit van de functie. Alle rijen nemen de metagegevens over van de functie waarmee de tabel is gekoppeld. Als dezelfde metagegevens opnieuw op rijniveau worden opgegeven, worden de metagegevenswaarden overschreven die zijn gedefinieerd op functieniveau.
OPMERKING: de definitie van het XML-bestandsschema is hetzelfde voor systeemeigen en beheerde code, met uitzondering van typedefinities die worden ondersteund. Bekijk de sectie 'De gegevens definiëren' bovenaan deze pagina voor een ander voorbeeld van hoe u dit definieert.
Nu hebt u alle gegevens gedefinieerd. In het volgende voorbeeld ziet u hoe u deze kunt openen.
1 namespace WEX.Examples
2 {
3 using Microsoft.VisualStudio.TestTools.UnitTesting;
4 using System;
5 using System.Collections;
6 using WEX.Logging.Interop;
7 using WEX.TestExecution;
8
9 [TestClass]
10 public class CSharpDataDrivenTests
11 {
12 [TestMethod]
15 [DataSource("Table:CSharpDataDrivenTests.xml#FirstTable")]
16 public void First()
17 {
18 Console.WriteLine("Left is " + m_testContext.DataRow["Left"].ToString());
19
20 Log.Comment("In CSharpDataDrivenTests.First");
21 }
22
23 [TestMethod]
24 public void Second()
25 {
26 Log.Comment("In CSharpDataDrivenTests.Second");
27 Verify.IsTrue(true);
28 }
29
30 public TestContext TestContext
31 {
32 get { return m_testContext; }
33 set { m_testContext = value; }
34 }
35
36 private TestContext m_testContext;
37 }
38 }
Het koppelen van de XML-tabel aan een bepaalde testmethode in beheerde code is vergelijkbaar met systeemeigen code; pas gewoon de metagegevens van 'DataSource' toe. Net als voorheen bestaat het uit drie delen:
- 'Tabel:' : als u de gegevensbron wilt identificeren als een XML-tabel.
- 'CSharpDataDrivenTests.xml' - het bestand dat de XML-tabel bevat.
- '#FirstTable': na de delimeter '#' identificeert de waarde 'FirstTable' de specifieke tabel in het XML-document dat moet worden gebruikt. TAEF doorzoekt het XML-bestand voor een tabelelement met een id-kenmerk dat overeenkomt met de opgegeven waarde.
U ziet dat de functie Second niet gegevensgestuurd is. U kunt ervoor kiezen om slechts enkele van uw tests te gebruiken om gegevensgestuurd te zijn. U hebt ook de mogelijkheid om elke test de tabel te laten definiëren in een ander XML-bestand.
In regel 36 definieer je een privé-eigenschap TestContext, zoals VSTS aanbeveelt in de TestContext Class. U definieert ook openbare beoordelaars voor deze eigenschap (regel 30 tot en met 34). Intern laadt TAEF de woordenlijsteigenschap van TestContext met de bijbehorende gegevensset in focus.
TestContext is gedefinieerd in Microsoft.VisualStudio.TestTools.UnitTesting. Zie regel 3 in het bovenstaande voorbeeld. U moet dit al opnemen als referentie in uw beheerde testcreatie. Dus zijn er geen aanvullende verwijzingen vereist voor het ontwerpen van gegevensgestuurde tests.
In regel 18 van het bovenstaande voorbeeld ziet u hoe u gegevens in de functie ophaalt. U ziet dat de gegevens beschikbaar zijn in m_testContext.DataRow.
naam in plaats van index om een DataRow te identificeren
Met TAEF kunt u een zinvollere eigenschap 'Naam' hebben in plaats van de index om een DataRow in uw DataSource te identificeren. U doet dit door eenvoudigweg metagegevens van 'Naam' toe te voegen op rijniveau in uw gegevensbron. Ons eerste voorbeeld op deze pagina kan als volgt worden gewijzigd om deze functie te gebruiken:
1 <?xml version="1.0"?>
2 <Data>
3 <Table id ="Table1">
4 <ParameterTypes>
5 <ParameterType Name="Size">Int32</ParameterType>
6 <ParameterType Name="Color">String</ParameterType>
7 <ParameterType Name="Transparency">Boolean</ParameterType>
8 </ParameterTypes>
9 <Row Name='BlueTransparent' Priority="1" Owner="C2">
10 <Parameter Name="Size">12</Parameter>
11 <Parameter Name="Color">Blue</Parameter>
12 <Parameter Name="Transparency">True</Parameter>
13 </Row>
14 <Row Priority="2" Owner="wex">
15 <Parameter Name="Size">4</Parameter>
16 <Parameter Name="Color">White</Parameter>
17 <Parameter Name="Transparency">False</Parameter>
18 </Row>
19 <Row Name='BlackTransparent' Owner="C2">
20 <Parameter Name="Size">9</Parameter>
21 <Parameter Name="Color">Black</Parameter>
22 <Parameter Name="Transparency">True</Parameter>
23 </Row>
24 </Table>
25 ...
39 </Data>
In het bovenstaande gewijzigde voorbeeld komt 'BlueTransparent' overeen met index 0. De rij met index 1 heeft er geen speciale naam aan gegeven en de rij met index 2 heeft de naam 'BlackTransparent eraan gekoppeld. U kunt nog steeds een selectiequery gebruiken om te zoeken naar index 0 of 2 in 'Tabel1', waarna de juiste rij wordt gevonden. Maar bij het uitvoeren of weergeven van het dll-bestand, in plaats van het volgende te zien:
<qualified name of the test method>#<index>
in plaats daarvan ziet u:
<qualified name of the test method>#<name property provided at Row level>
voor de rijen waar het kenmerk 'Naam' wordt opgegeven op rijniveau. Als de eigenschap 'Naam' niet is opgegeven voor een rij, zoals in het geval van index 1 hierboven, wordt standaard<index> toegevoegd aan de gekwalificeerde naam van de methode.
Houd er rekening mee dat u door het opgeven van een kenmerk 'Naam' op rijniveau, in wezen de manier wijzigt waarop TAEF de naam van het exemplaar van de methode aanroept met de bijbehorende rijgegevens.
DataSource als runtime-parameter
TAEF biedt ondersteuning voor het leveren van de gegevensbron als runtimeparameter. De syntaxis hiervoor is als volgt:
te <test dll names> /p:<DataSource runtime name>=Table:<DataSoure XML file>#<Table Id>
Tijdens het ontwerpen van de test in kwestie moet u de naam 'p:<DataSource-runtimenaam>' opgeven als uw gegevensbron. Houd er rekening mee dat u tijdens runtime de volledige tekenreeks moet opgeven ( de naam van het XML-bestand en de tabel-id samen). De TableId wordt naar verwachting niet geleverd als testmetagegevens als uw gegevensbron tijdens runtime wordt geleverd. Het voorvoegsel 'Tabel:' geeft aan dat u op zoek bent naar een tabelgegevensbron.
U kunt dit proberen met een van de voorbeelden die beschikbaar zijn op de releaseshare:
te Examples\CPP.RuntimeDataSource.Example.dll /p:MyDataSource=Table:RuntimeDataSourceExample.xml#SimpleTable
DataSource als een hulpbron
Met TAEF kunt u uw DataSource toevoegen als een resource van uw testmodule, zolang deze voldoet aan het volgende:
In het geval van systeemeigen testmodules kunt u dit doen door uw DataSource op te geven als resource-id of resourcenaam. Hier volgt een codevoorbeeld:
BEGIN_TEST_METHOD(ResourceNameDataSource)
TEST_METHOD_PROPERTY(L"DataSource", L"Table:MyResourceName#SimpleTable")
END_TEST_METHOD()
'MyResourceName' is de resourcenaam zoals die is gedefinieerd in het bestand ResourceDataSource.rc in dit geval.
MyResourceName DATASOURCE_XML "ResourceDataSource.xml"
In het geval van beheerde testmodules kan de resource alleen op een bepaalde manier worden opgegeven, zoals wordt weergegeven in de bronnen bestandsfragment dat hieronder wordt weergegeven:
LANGUAGE_NEUTRAL_MANAGED_RESOURCES = CSharpAdvancedDataDrivenTests.xml
De specificatie voor metagegevens van DataSource blijft hetzelfde als bij het opgeven van het XML-bestand datasource. Net als in beheerde code kunt u de resourcenaam hetzelfde maken als de NAAM van het XML-bestand. Het is daarom belangrijk om te begrijpen dat TAEF eerst zoekt naar de aanwezigheid van het daadwerkelijke bestand met de naam van de gegevensbron. Als een dergelijk XML-bestand niet wordt gevonden, gaat het alleen verder met het zoeken naar testresource in de testmodule met de opgegeven resourcenaam of id. Aangezien het opgeven van de DataSource als een resource opnieuw moet worden ge compileerd, kunt u van dit ontwerp profiteren door het XML-bestand van de DataSource te kopiëren naar dezelfde locatie als de test-DLL tijdens het ontwikkelen (en de naam van de resourcenaam gelijk te stellen aan de naam van het XML-bestand). Wanneer u klaar bent met testen, kopieert u de XML terug naar de map met code en compileert u deze opnieuw als een resource. Vergeet niet om het XML-bestand uit de uitvoeringsmap te verwijderen. :)
voorbeeld van stapsgewijze instructies
Als u verschillende aspecten van gegevensgestuurde tests op basis van tabellen wilt begrijpen, leest u een aantal voorbeelden van stapsgewijze instructies: