Condividi tramite


Origine dati WMI

Assicurarsi di avere familiarità con l'esecuzione di base di TAEF e sapere come creare test usando questa sezione.

Priorità bassa

"WMI" è l'acronimo di "Strumentazione gestione Windows". Usando Common Information Model (CIM), ovvero lo standard del settore per rappresentare i sistemi. Strumentazione gestione Windows offre un modo unificato per accedere alle informazioni di gestione del sistema.

Come aiuta i test?

Usando il supporto della query WMI disponibile come WMI DataSource in TAEF, è possibile aggiungere una precondizione al test e ottenere informazioni sulle risorse nel computer di test prima di eseguire il test. Ecco alcuni esempi del tipo di query che è possibile eseguire usando WMI:

  • Verificare se il computer in esecuzione è un portatile ed eseguire il test solo se è un portatile.
  • Verificare se un Service Pack è stato installato nel computer di test ed eseguire il test solo se è stato.
  • Recuperare tutte le unità rimovibili e le unità disco rigido locale nel computer di test ed eseguire il test per ognuna delle unità che corrispondono alla query.
  • Eseguire il test solo se il computer di test non è aggiunto al dominio OR
  • Eseguire il test solo se il computer di test è aggiunto al dominio e recuperare il nome di dominio.

Ciò potrebbe aver dato un'idea su dove e come è possibile sfruttare WMI DataSource per il test. Verrà illustrato come aggiungere il supporto di questa query WMI durante la creazione di un test TAEF.

L'unico metadati speciale necessario per eseguire il test di un test WMI DataSource è "DataSource". La sintassi DataSource deve essere simile alla seguente:

[DataSource("WMI:<WQL query>")]

Oppure nel codice nativo:

TEST_METHOD_PROPERTY(L"DataSource", L"WMI:<WQL query>")]

È necessario aver notato che il valore DataSource inizia con "WMI:" che consente a TAEF di sapere che questa è effettivamente l'origine dati per un test che dipende dal risultato della query WMI e la distingue anche dal test basato sui dati. Questa è una buona opportunità per ricordare che attualmente TAEF non supporta un test per essere entrambi - un test basato su dati e un test che dipende dal risultato della query WMI.

La domanda successiva è naturalmente come scrivere query WQL per cosa si sta cercando? La sintassi della query WQL è molto simile alle query SQL semplificate. Esistono alcuni esempi molto validi di query fornite nelle attività WMI per script e applicazioni. Ecco alcuni esempi:

SELECT Description, DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'
Eseguire il test nel servizio "Temi" dopo aver scoperto che è Descrizione, DesktopInteract e Proprietà ProcessId che si intende usare nei test.

Funzionalità SELECT, FunzionalitàDescriptions FROM Win32_Printe
Eseguire il test per ogni stampante connessa a questo computer. Consentire al test di accedere alle funzionalità e alle funzionalitàDescriptions per ogni stampante.

SELECT Name, User, Location FROM Win32_StartupCommand
Eseguire il test per ogni processo eseguito all'avvio di Windows. Per ogni processo, il test conosce il nome del processo, dove si trova (posizione) e l'esecuzione del processo da parte dell'utente.

È possibile trovare altri esempi nella documentazione precedente, nonché nel file con estensione cs e nel file di intestazione negli esempi aperti. La sintassi generale e semplificata è la seguente:

SELECT <comma separated properties> FROM <WMI Class name> [WHERE <add condition on some properties>]

Negli esempi appena visualizzati, Win32_Service, Win32_Printer e Win32_StartupCommand sono tutte classi WMI. È possibile cercare le classi WMI nelle classi WMI.

TAEF non supporta il recupero delle proprietà di sistema.

Dietro la scena TAEF eseguirà la query per l'utente e conferma il risultato. Se almeno un oggetto viene restituito come risultato della query, il test viene eseguito per ogni oggetto restituito. Se la query WQL non restituisce oggetti, il test viene registrato come Bloccato con queste informazioni ed esecuzione passa al test successivo.

Controllare o verificare la query prima di creare il test sembra essere un'ottima idea ed è un processo molto semplice:

  • Nella finestra di dialogo di esecuzione o nel prompt dei comandi richiamare "wbemtest.exe"
  • Fare clic sul pulsante "Connetti" nell'angolo superiore destro.
  • Assicurarsi che lo spazio dei nomi sia "root\cimv2" prima di fare clic di nuovo su "Connetti" nell'angolo superiore destro.
  • In "IWbemServices", fare clic su "Query"
  • Immettere la query nella casella di modifica visualizzata e fare clic su "Applica"

NOTA: "IWbemService" include diverse altre opzioni che possono essere utili per la query. Ad esempio, l'uso di "Classi Enum" e la modifica del pulsante di opzione su "ricorsivo" consente di visualizzare tutte le classi WMI nel sistema.

Recupero delle proprietà eseguite tramite la query WMI

A questo momento si ha un'idea di come creare una query WMI per un metodo di test e come applicarla come metadati durante la creazione di un test. È anche possibile verificare che la query sia valida usando wbemtest.exe. Si esaminerà ora come recuperare i valori delle proprietà da cercare.

Le nozioni di base sul recupero di queste informazioni sono molto simili al recupero dei valori per il test basato sui dati. Ad esempio, nel codice gestito, questo aspetto sarà il seguente:

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}

Le righe 24-30 nell'esempio precedente sono esattamente ciò che è necessario per un test gestito basato sui dati. È stata definita una proprietà TestContext privata e sono stati forniti getter pubblici e setter su di esso per TAEF per impostare i valori corretti. Usando la proprietà TestContext privata, è possibile recuperare il valore corrente per una delle proprietà dell'oggetto risultante della query WMI recuperate da TAEF.

Il codice nativo per il recupero delle proprietà WMI è molto simile. Analogamente ai test basati sui dati nativi, si userà TestData per ottenere i valori delle proprietà. Si consideri ad esempio il test per ottenere le proprietà della stampante predefinita. Il file di intestazione autori di questo test come segue:

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()

Per questo motivo, il codice di recupero, nel file cpp è simile al seguente:

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    }

Contabilità dei possibili valori di proprietà NULL

La parte da tenere presente è che la query WMI potrebbe non restituire sempre una proprietà non null. È possibile che il valore della proprietà WMI restituito sia "Null". Se si ritiene che la proprietà che si sta cercando potrebbe essere "Null" in alcuni scenari, verificare la proprietà prima di verificare o provare a usarla.

Nel codice di test gestito, ad esempio, TestContext archivierà i valori Null come oggetto di tipo DBNull. È necessario verificare se l'oggetto è di tipo DBNull prima di provare a eseguire il cast del valore risultante al tipo previsto. Per verificarlo, eseguire questa procedura:

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}

Nel test precedente, ad esempio, "Compressed", "MaximumComponentLength" e "Availability" può essere null in alcuni scenari (quando la query restituisce unità rimovibili come unità floppy). Si vuole assicurarsi che il test si comporta in modo appropriato in questi casi. Verso questa fine, recuperare il valore della proprietà come oggetto e verificare se è di tipo "DBNull". Se è, significa che il valore della proprietà restituito è null. In caso contrario, il valore restituito non era null e quindi valido, quindi eseguirne il cast ai tipi appropriati e usarlo per il test.

Lo stesso vale anche con le API di recupero native. Il valore della proprietà restituito potrebbe essere NULL. Ciò significa che è necessario verificare se TestData ha recuperato correttamente il valore senza usare una chiamata di verifica (poiché non è possibile recuperare potrebbe essere perché il valore è Null). Ad esempio, potrebbe essere disponibile un metodo di test che dipende da una query 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()

È possibile che sia stato restituito "Disponibilità e "MaximumComponentLength" come valori NULL. Scrivere quindi il test per tenere conto di questo come segue:

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    }