Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
Kontrollera att du är bekant med grundläggande körning av TAEF och vet hur du skapar tester med den innan du fortsätter med det här avsnittet.
Bakgrund
"WMI" står för "Windows Management Instrumentation". Använda Common Information Model (CIM), som är branschstandarden för att representera system. Windows Management Instrumentation är ett enhetligt sätt att komma åt systemhanteringsinformation.
Hur hjälper det mina tester?
Med hjälp av WMI-frågestöd som är tillgängligt som WMI DataSource i TAEF kan du lägga till en förhandsvillkor i testet samt få information om resurserna på testdatorn innan du kör testet. Här är några exempel på den typ av fråga som du kan göra med hjälp av WMI:
- Kontrollera om maskinen som testet körs på är en bärbar dator och kör testet endast om det är en bärbar dator.
- Kontrollera om ett Service Pack har installerats på testdatorn och kör testet endast om det har varit det.
- Hämta alla flyttbara enheter och lokala hårddiskar på testdatorn och kör testet för var och en av de enheter som matchar frågan.
- Kör testet endast om testdatorn inte är domänansluten ELLER
- Kör testet endast om testdatorn är domänansluten och hämtar domännamnet.
Det skulle förhoppningsvis ha gett dig en uppfattning om var och hur du kan använda WMI DataSource för din testning. Nu ska vi titta på hur du lägger till det här WMI-frågestödet när du redigerar ett TAEF-test.
De enda särskilda metadata du behöver för att göra testet till ett WMI DataSource-test är "DataSource". Syntaxen för DataSource måste se ut så här:
[DataSource("WMI:<WQL query>")]
Eller i intern kod:
TEST_METHOD_PROPERTY(L"DataSource", L"WMI:<WQL query>")]
Du måste ha märkt att DataSource-värdet börjar med "WMI:" som låter TAEF veta att detta verkligen är datakällan för ett test som är beroende av WMI-frågeresultatet och även skiljer det från datadrivna tester. Det här är ett bra tillfälle att nämna att TAEF för närvarande inte stöder ett test för att vara både - ett datadrivet test samt ett test som är beroende av WMI-frågeresultatet.
Nästa fråga är naturligtvis hur man skriver WQL-frågor för det du letar efter? WQL-frågesyntaxen liknar förenklade SQL-frågor. Det finns några mycket bra exempel på frågor som tillhandahålls i WMI-uppgifter för skript och program. Här är några exempel:
SELECT Description, DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'
Kör testet på "Teman"-tjänsten när du har fått reda på egenskaperna Description, DesktopInteract och ProcessId som du tänker använda i testningen.
Välj kapabiliteter, CapabilityDescriptions FRÅN Win32_Printe
Kör testet för varje skrivare som är ansluten till den här datorn. Tillåt att testet får åtkomst till funktionerna och kapacitetsbeskrivningarna för varje skrivare.
SELECT Name, User, Location FROM Win32_StartupCommand
Kör testet för varje process som körs vid Windows-start. För varje process ska testet veta vad namnet på processen är, var den finns (plats) och vilken användare processen körs som.
Du hittar fler exempel i dokumentationen som nämns ovan samt i .cs fil och rubrikfil i de exempel som du har öppnat. Den allmänna, över förenklade syntaxen är följande:
SELECT <comma separated properties> FROM <WMI Class name> [WHERE <add condition on some properties>]
I de exempel som du nyss såg är Win32_Service, Win32_Printer och Win32_StartupCommand alla WMI-klasser. Du kan leta upp WMI-klasserna i WMI-klasser.
TAEF stöder inte hämtning av systemegenskaper.
Bakom scenen kör TAEF frågan åt dig och bekräftar resultatet. Om minst ett objekt returneras som ett resultat av frågan körs testet för varje returnerat objekt. Om WQL-frågan inte returnerar några objekt loggas testet som Blockerat med den här informationen och körningen går vidare till nästa test.
Det verkar vara en bra idé att kontrollera eller verifiera frågan innan du redigerar testet, och det är en mycket enkel process:
- Antingen från körningsdialogrutan eller från ett kommandofönster använd "wbemtest.exe"
- Klicka på knappen "Anslut" i det övre högra hörnet.
- Kontrollera att namnområdet är "root\cimv2" innan du klickar på Anslut igen i det övre högra hörnet.
- Under "IWbemServices" klickar du på "Fråga"
- Ange din fråga i redigeringsrutan som visas och klicka på "Tillämpa"
OBS! "IWbemService" har flera andra alternativ som kan hjälpa dig med din fråga. Om du till exempel använder "Enum-klasser" och ändrar radioknappen till "rekursiv" kan du se alla WMI-klasser på systemet.
Hämta egenskaper som efterfrågas med hjälp av WMI-frågan
Nu har du en uppfattning om hur du hittar på en WMI-fråga för en testmetod och hur du använder den som metadata när du redigerar ett test. Du vet också hur du bekräftar att frågan är giltig med hjälp av wbemtest.exe. Nu ska vi titta på hur du hämtar de egenskapsvärden som du letade efter.
Grunderna för att hämta den här informationen liknar hämtning av värden för ditt datadrivna test. I hanterad kod skulle det till exempel se ut så här:
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}
Raderna 24–30 i exemplet ovan är exakt vad som krävs för ett hanterat datadrivet test. Du har definierat en privat TestContext-egenskap och angett offentlig getter och setter på den så att TAEF kan ange rätt värden. Med hjälp av den privata egenskapen TestContext kan du hämta det aktuella värdet för någon av WMI-frågeresultatobjektets egenskaper som du hämtade från TAEF.
Den interna koden för att hämta WMI-egenskaperna är mycket lik. Precis som med interna datadrivna tester använder du TestData för att hämta egenskapsvärdena. Låt oss till exempel överväga testet för att hämta egenskaperna för standardskrivaren. Huvudfilen skapar det här testet så här:
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()
För detta ser vår hämtningskod i cpp-filen ut så här:
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 }
Redovisning av möjliga NULL-egenskapsvärden
Den del som du bör tänka på är att WMI-frågan kanske inte alltid returnerar en egenskap som inte är null. Det kan finnas tillfällen då det returnerade WMI-egenskapsvärdet är "null". Om du tror att den egenskap som du letar efter kan vara "null" i vissa scenarier kontrollerar du den innan du verifierar eller försöker använda den.
I till exempel hanterad testkod lagrar TestContext null-värdena som ett objekt av typen DBNull. Du måste kontrollera om objektet är av typen DBNull innan du försöker omvandla det resulterande värdet till den typ som du förväntar dig att det ska vara. Låt oss ta en titt:
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}
I testet ovan kan till exempel "Komprimerad", "MaximumComponentLength" och "Tillgänglighet" vara null i vissa scenarier (när frågan returnerar flyttbara enheter som diskettenheter). Du vill se till att testet fungerar korrekt i sådana fall. För detta ändamål hämtar du egenskapsvärdet som ett objekt och kontrollerar om det är av typen "DBNull". Om så är fallet, innebär det att det returnerade egenskapsvärdet var null. Om det inte är det var det returnerade värdet inte null och därmed giltigt – så omvandla det till lämpliga typer och använd det för testningen.
Detsamma gäller för API:er för inbyggda hämtningar – egenskapsvärdet som returneras kan vara NULL. Det innebär att du måste kontrollera om TestData har hämtat värdet utan att använda ett verifieringsanrop (eftersom det kan bero på att värdet är null). Du kan till exempel ha en testmetod som är beroende av en WMI-fråga:
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()
Du kan ha "Tillgänglighet och "MaximumComponentLength" returnerade som NULL-värden. Så skriv testet för att ta hänsyn till detta så här:
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 }