Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Než budete pokračovat v této části, ujistěte se, že znáte základní provádění TAEF a víte, jak s jeho pomocí vytvářet testy.
Pozadí
"WMI" znamená "Windows Management Instrumentation". Použití modelu CIM (Common Information Model), což je oborový standard představující systémy. Windows Management Instrumentation poskytuje jednotný způsob přístupu k informacím o správě systému.
Jak to pomůže mým testům?
Pomocí podpory dotazů rozhraní WMI, která je k dispozici jako zdroj dat WMI v taEF, můžete před spuštěním testu přidat předběžnou podmínku a získat informace o prostředcích na testovacím počítači. Tady je několik příkladů typu dotazu, který můžete provést pomocí rozhraní WMI:
- Zkontrolujte, jestli je počítač, na kterém test běží, přenosný počítač, a test spusťte jenom v případě, že se jedná o přenosný počítač.
- Zkontrolujte, jestli je na testovacím počítači nainstalovaná aktualizace Service Pack, a spusťte test pouze v případě, že byla.
- Načtěte všechny vyměnitelné jednotky a místní pevné disky na testovacím počítači a spusťte test pro každou jednotku, která odpovídá dotazu.
- Spusťte test jenom v případě, že testovací počítač není připojený k doméně NEBO
- Spusťte test pouze v případě, že je testovací počítač připojený k doméně a načte název domény.
To by vám snad poskytlo představu o tom, kde a jak můžete využít WMI DataSource pro testování. Pojďme se podívat, jak přidat podporu tohoto dotazu WMI při vytváření testu TAEF.
Jedinými speciálními metadaty, které potřebujete k tomu, aby váš test byl testem WMI DataSource, je "Zdroj dat". Syntaxe Zdroje dat musí vypadat takto:
[DataSource("WMI:<WQL query>")]
Nebo v nativním kódu:
TEST_METHOD_PROPERTY(L"DataSource", L"WMI:<WQL query>")]
Je nutné si všimnout, že hodnota DataSource začíná na "WMI:", která taEF informuje, že se jedná o zdroj dat pro test, který závisí na výsledku dotazu rozhraní WMI, a také jej odlišuje od testu řízeného daty. Je to dobrá příležitost zmínit, že v současné době taEF nepodporuje test, který by byl obojí – test řízený daty i test, který závisí na výsledku dotazu WMI.
Další otázka je přirozeně, jak psát dotazy WQL pro to, co hledáte? Syntaxe dotazů WQL je velmi podobná zjednodušeným dotazům SQL. V úlohách rozhraní WMI pro skripty a aplikace jsou k dispozici některé velmi dobré příklady dotazů. Tady je několik příkladů:
SELECT Description, DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'
Po zjištění vlastností Description, DesktopInteract a ProcessId, které máte v úmyslu použít při testování, spusťte test ve službě „Motivy“.
Možnosti SELECT, popisy funkcí FROM Win32_Printe
Spusťte test pro každou tiskárnu připojenou k tomuto počítači. Povolte testu přístup k funkcím a popisům CapabilityDescriptions pro každou tiskárnu.
SELECT Name, User, Location FROM Win32_StartupCommand
Spusťte test pro každý proces, který se spustí při spuštění systému Windows. U každého procesu dejte testu vědět, jaký je název procesu, kde se nachází (Umístění) a pod jakým uživatelem proces běží.
Další příklady najdete v dokumentaci uvedené výše i v souboru .cs a v souborech hlaviček v příkladech, které jste otevřeli. Obecně zjednodušená syntaxe je následující:
SELECT <comma separated properties> FROM <WMI Class name> [WHERE <add condition on some properties>]
V příkladech, které jste právě viděli, Win32_Service, Win32_Printer a Win32_StartupCommand jsou všechny třídy rozhraní WMI. Třídy služby WMI můžete vyhledat ve třídách služby WMI.
TaEF nepodporuje načítání systémových vlastností.
TaEF na pozadí provede dotaz za vás a potvrdí výsledek. Pokud se v důsledku dotazu vrátí alespoň jeden objekt, provede se test pro každý vrácený objekt. Pokud dotaz WQL nevrací žádné objekty, test se zaprotokoluje jako blokovaný s těmito informacemi a provádění se přesune na další test.
Kontrola nebo ověření dotazu před vytvořením testu vypadá jako skvělý nápad a je to velmi jednoduchý proces:
- Buď z dialogového okna Spustit, nebo z příkazového řádku spusťte "wbemtest.exe"
- Klikněte na tlačítko Připojit v pravém horním rohu.
- Před dalším kliknutím na Připojit v pravém horním rohu se ujistěte, že váš obor názvů je root\cimv2.
- V části IWbemServices klikněte na Dotaz.
- Zadejte dotaz do pole pro úpravy, které se zobrazí, a klikněte na Použít.
POZNÁMKA: IWbemService má několik dalších možností, které by vám mohly pomoct s dotazem. Například použití "Výčtové třídy" a změna přepínače na "rekurzivní" vám pomůže zobrazit všechny třídy WMI v systému.
Načítání vlastností dotazovaných pomocí dotazu WMI
Teď máte představu o tom, jak vytvořit dotaz rozhraní WMI pro testovací metodu a jak ho použít jako metadata při vytváření testu. Také víte, jak ověřit platnost dotazu pomocí wbemtest.exe. Teď se podíváme, jak načíst hodnoty vlastností, které jste hledali.
Základní informace o načítání těchto informací jsou velmi podobné načtení hodnot pro test řízený daty. Například ve spravovaném kódu by to vypadalo takto:
1 namespace WEX.Examples
2 {
3 using Microsoft.VisualStudio.TestTools.UnitTesting;
4 using System;
5 using System.Collections;
6 using System.Data;
7 using WEX.Logging.Interop;
8 using WEX.TestExecution;
9
10 [TestClass]
11 public class CSharpWmiDataSourceExample
12 {
13 [TestMethod]
14 [DataSource("WMI:SELECT Description, DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'")]
15 public void ThemesTest()
16 {
17 String description = (String)m_testContext.DataRow["Description"];
18 Boolean desktopInteract = (Boolean)m_testContext.DataRow["DesktopInteract"];
19 UInt32 processId = (UInt32)m_testContext.DataRow["ProcessId"];
20 Log.Comment("Themes service is running on process " + processId.ToString() + " with desktop interact set to "
+ desktopInteract.ToString());
21 Log.Comment("Themes service description: " + description);
22 }
23 ...
24 public TestContext TestContext
25 {
26 get { return m_testContext; }
27 set { m_testContext = value; }
28 }
29
30 private TestContext m_testContext;
31 }
32}
Řádky 24–30 v příkladu výše jsou přesně to, co je potřeba pro spravovaný test řízený daty. Definovali jste soukromou vlastnost TestContext a poskytli k ní veřejné metody getter a setter, aby TAEF mohl nastavit správné hodnoty. Pomocí privátní vlastnosti TestContext můžete načíst aktuální hodnotu pro libovolný z vlastností výsledného objektu dotazu WMI, které jste získali z TAEF.
Nativní kód pro načtení vlastností rozhraní WMI je velmi podobný. Stejně jako u nativních testů řízených daty použijete TestData k získání hodnot vlastností. Podívejme se například na test získání vlastností výchozí tiskárny. Autoři souboru hlavičky tento test vytvářejí tímto způsobem:
1 // Test on the default printer and its driver name
2 BEGIN_TEST_METHOD(DefaultPrinterTest)
3 TEST_METHOD_PROPERTY(L"DataSource",
L"WMI:SELECT DriverName, DeviceId, LanguagesSupported FROM Win32_Printer WHERE Default = True")
4 END_TEST_METHOD()
V tomto případě náš kód pro načtení vypadá v souboru cpp takto:
1 void WmiExample::DefaultPrinterTest()
2 {
3 String deviceId;
4 VERIFY_SUCCEEDED(TestData::TryGetValue(L"DeviceId", deviceId));
5
6 String driverName;
7 VERIFY_SUCCEEDED(TestData::TryGetValue(L"DriverName", driverName));
8
9 TestDataArray<unsigned int> languagesSupported;
10 VERIFY_SUCCEEDED(TestData::TryGetValue(L"LanguagesSupported", languagesSupported));
11
12 Log::Comment(L"The default driver is " + deviceId + L" which is a " + driverName);
13 size_t count = languagesSupported.GetSize();
14 for (size_t i = 0; i < count; i++)
15 {
16 Log::Comment(String().Format(L"Language supported: %d", languagesSupported[i]));
17 }
18 }
Účtování možných hodnot vlastností NULL
Je třeba mít na paměti, že dotaz WMI nemusí vždy vracet nenulovou vlastnost. Někdy může docházet k tomu, že vrácená hodnota vlastnosti WMI má hodnotu null. Pokud si myslíte, že vlastnost, kterou hledáte, může být v některých scénářích null, zkontrolujte ji před ověřením nebo pokusem o jeho použití.
Ve spravovaném testovacím kódu například TestContext uloží hodnoty null jako objekt typu DBNull. Před pokusem o přetypování výsledné hodnoty na typ, který očekáváte, je nutné zkontrolovat, zda je objekt typu DBNull. Pojďme se podívat:
1 namespace WEX.Examples
2 {
3 using Microsoft.VisualStudio.TestTools.UnitTesting;
4 using System;
5 using System.Collections;
6 using System.Data;
7 using WEX.Logging.Interop;
8 using WEX.TestExecution;
9
10 [TestClass]
11 public class CSharpWmiDataSourceExample
12 {
13 [TestMethod]
14 [DataSource("WMI:SELECT MaximumComponentLength, Availability, DeviceId, DriveType, Compressed
FROM Win32_LogicalDisk WHERE DriveType=2 Or DriveType=3")]
15 public void LogicalDiskTest()
16 {
17 UInt32 driveType = (UInt32)m_testContext.DataRow["DriveType"];
18 Log.Comment("DeviceId is " + m_testContext.DataRow["DeviceId"]);
19 Log.Comment("DriveType is " + driveType.ToString());
20
21 object nullCheckCompressed = m_testContext.DataRow["Compressed"];
22 Log.Comment("Compressed's type is: " + nullCheckCompressed.GetType().ToString());
23 if (nullCheckCompressed.GetType() == typeof(DBNull))
24 {
25 Log.Comment("Compressed is NULL");
26 }
27 else
28 {
29 Boolean compressed = (Boolean)nullCheckCompressed;
30 Log.Comment("Compressed is " + compressed.ToString());
31 }
32
33 object nullCheckMaxComponentLength = m_testContext.DataRow["MaximumComponentLength"];
34 if (nullCheckMaxComponentLength.GetType() == typeof(DBNull))
35 {
36 Log.Comment("MaxComponentLength is NULL");
37 }
38 else
39 {
40 UInt32 maxComponentLength = (UInt32)nullCheckMaxComponentLength;
41 Log.Comment("MaxComponentLength is " + maxComponentLength.ToString());
42 }
43
44 object nullCheckAvailability = m_testContext.DataRow["Availability"];
45 if (nullCheckAvailability.GetType() == typeof(DBNull))
46 {
47 Log.Comment("Availability is NULL");
48 }
49 else
50 {
51 UInt32 availability = (UInt32)nullCheckAvailability;
52 Log.Comment("Availability is " + availability.ToString());
53 }
54 }
55 ...
56 public TestContext TestContext
57 {
58 get { return m_testContext; }
59 set { m_testContext = value; }
60 }
61
62 private TestContext m_testContext;
63 }
64}
Například v předchozím testu mohou být v některých scénářích hodnoty "Compressed", "MaximumComponentLength" a "Availability" null (když dotaz vrátí vyměnitelné jednotky, například disketové jednotky). Chcete se ujistit, že se test v takových případech chová správně. Za tímto účelem načtěte hodnotu vlastnosti jako objekt a zkontrolujte, jestli je typu "DBNull". Pokud ano, znamená to, že vrácená hodnota vlastnosti byla null. Pokud tomu tak není, vrácená hodnota nebyla null a proto je platná – proto ji přetypujte na příslušné typy a použijte ji pro testování.
Totéž platí i s nativními rozhraními API pro načítání – vrácená hodnota vlastnosti může být NULL. To znamená, že potřebujete zkontrolovat, jestli TestData úspěšně načetl hodnotu bez použití volání ověřování (protože nemožnost načtení může být způsobena tím, že hodnota je null). Můžete mít například testovací metodu, která závisí na dotazu rozhraní WMI:
1 // Test on only local (drive type = 3) or removable (drive type = 2) harddrive
2 BEGIN_TEST_METHOD(LocalOrRemovableHardDriveTest)
3 TEST_METHOD_PROPERTY(L"DataSource", L"WMI:SELECT DeviceId, DriveType, Availability,
MaximumComponentLength FROM Win32_LogicalDisk WHERE DriveType=2 OR DriveType=3")
4 END_TEST_METHOD()
Jako hodnoty NULL může být vrácena hodnota Availability a MaximumComponentLength. Proto si napište test tak, aby to vypadalo takto:
1 void WmiExample::LocalOrRemovableHardDriveTest()
2 {
3 String deviceId;
4 VERIFY_SUCCEEDED(TestData::TryGetValue(L"DeviceId", deviceId));
5 int driveType;
6 VERIFY_SUCCEEDED(TestData::TryGetValue(L"DriveType", driveType));
7
8 unsigned int maxComponentLength;
9 if (SUCCEEDED(TestData::TryGetValue(L"MaximumComponentLength", maxComponentLength)))
10 {
11 Log::Comment(String().Format(L"MaximumComponentLength: %d", maxComponentLength));
12 }
13
14 unsigned int availability;
15 if (SUCCEEDED(TestData::TryGetValue(L"Availability", availability)))
16 {
17 Log::Comment(String().Format(L"Availability: %d", availability));
18 }
19
20 Log::Comment(L"DeviceId: " + deviceId);
21 Log::Comment(String().Format(L"DriveType: %d", driveType));
22 }