Source de données WMI
Vérifiez que vous êtes familiarisé avec l’exécution de base de TAEF et que vous savez comment créer des tests à l’aide de celui-ci, avant de passer à cette section.
Fond
« WMI » signifie « Windows Management Instrumentation ». Utilisation du Common Information Model (CIM), qui est la norme du secteur pour représenter les systèmes. Windows Management Instrumentation fournit un moyen unifié d’accéder aux informations de gestion du système.
Comment cela aide-t-il mes tests ?
À l’aide de la prise en charge des requêtes WMI disponible en tant que source de données WMI dans TAEF, vous pouvez ajouter une condition préalable à votre test et obtenir des informations sur les ressources sur la machine de test avant d’exécuter votre test. Voici quelques exemples du type de requête que vous pouvez effectuer à l’aide de WMI :
- Vérifiez si la machine sur laquelle le test s’exécute est un ordinateur portable et exécutez le test uniquement s’il s’agit d’un ordinateur portable.
- Vérifiez si un Service Pack a été installé sur la machine de test et exécutez le test uniquement s’il l’a été.
- Récupérez tous les lecteurs amovibles et lecteurs de disque dur locaux sur la machine de test et exécutez le test pour chacun des lecteurs qui correspondent à la requête.
- Exécuter le test uniquement si l’ordinateur de test n’est pas joint au domaine OU
- Exécutez le test uniquement si la machine de test est jointe à un domaine et récupérez le nom de domaine.
Nous l’espérons, cela vous aurait donné une idée de l’emplacement et de la façon dont vous pouvez tirer parti de WMI DataSource pour vos tests. Voyons comment ajouter cette prise en charge des requêtes WMI lors de la création d’un test TAEF.
Les seules métadonnées spéciales dont vous avez besoin pour faire de votre test un test WMI DataSource sont « DataSource ». La syntaxe DataSource doit se présenter comme suit :
[DataSource("WMI:<WQL query>")]
Ou en code natif :
TEST_METHOD_PROPERTY(L"DataSource", L"WMI:<WQL query>")]
Vous devez avoir remarqué que la valeur DataSource commence par « WMI : », ce qui permet à TAEF de savoir qu’il s’agit bien de la source de données d’un test qui dépend du résultat de la requête WMI et la distingue également du test piloté par les données. Il s’agit d’une bonne occasion de mention qu’actuellement TAEF ne prend pas en charge un test pour être à la fois un test piloté par les données et un test qui dépend du résultat de la requête WMI.
La question suivante est naturellement comment écrire des requêtes WQL pour ce que vous recherchez ? La syntaxe de requête WQL est très similaire aux requêtes SQL simplifiées. Il existe de très bons exemples de requêtes fournies dans les tâches WMI pour les scripts et les applications. Voici quelques exemples :
SELECT Description, DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'
Exécutez le test sur le service « Thèmes » après avoir trouvé les propriétés Description, DesktopInteract et ProcessId que vous envisagez d’utiliser dans votre test.
SELECT Capabilities, CapabilityDescriptions FROM Win32_Printe
Exécutez le test pour chaque imprimante connectée à cet ordinateur. Autorisez le test à accéder aux propriétés Capabilities et CapabilityDescriptions pour chaque imprimante.
SELECT Name, User, Location FROM Win32_StartupCommand
Exécutez le test pour chaque processus exécuté au démarrage de Windows. Pour chaque processus, indiquez au test quel est le nom du processus, où il se trouve (Emplacement) et quel utilisateur le processus s’exécute.
Vous trouverez d’autres exemples dans la documentation mentionnée ci-dessus, ainsi que dans le fichier .cs et le fichier d’en-tête dans les exemples que vous avez ouverts. La syntaxe générale et trop simplifiée est la suivante :
SELECT <comma separated properties> FROM <WMI Class name> [WHERE <add condition on some properties>]
Dans les exemples que vous venez de voir, Win32_Service, Win32_Printer et Win32_StartupCommand sont toutes des classes WMI. Vous pouvez rechercher les classes WMI dans les classes WMI.
TAEF ne prend pas en charge la récupération des propriétés système.
En arrière-plan, TAEF exécute la requête pour vous et confirme le résultat. Si au moins un objet est retourné à la suite de la requête, le test est exécuté pour chaque objet retourné. Si la requête WQL ne retourne aucun objet, le test est journalisé comme Bloqué avec ces informations et l’exécution passe au test suivant.
La vérification ou la vérification de votre requête avant la création de votre test semble être une bonne idée, et il s’agit d’un processus très simple :
- À partir de la boîte de dialogue d’exécution ou d’une invite de commandes, appelez « wbemtest.exe »
- Cliquez sur le bouton « Se connecter » dans le coin supérieur droit.
- Vérifiez que votre espace de noms est « root\cimv2 » avant de cliquer à nouveau sur « Se connecter » dans le coin supérieur droit.
- Sous « IWbemServices », cliquez sur « Requête »
- Entrez votre requête dans la zone d’édition qui s’affiche, puis cliquez sur « Appliquer »
REMARQUE : « IWbemService » dispose de plusieurs autres options qui peuvent vous aider avec votre requête. Par exemple, l’utilisation de « Classes Enum » et la modification de la case d’option sur « récursive » vous aideront à voir toutes les classes WMI sur le système.
Récupération des propriétés interrogées à l’aide de la requête WMI
À présent, vous avez une idée de la façon de créer une requête WMI pour une méthode de test et de l’appliquer en tant que métadonnées lors de la création d’un test. Vous savez également comment vérifier que la requête est valide à l’aide de wbemtest.exe. Voyons maintenant comment récupérer les valeurs de propriété que vous recherchiez.
Les principes de base de la récupération de ces informations sont très similaires à la récupération de valeurs pour votre test piloté par les données. Par exemple, dans le code managé, cela se présente comme suit :
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}
Les lignes 24 à 30 de l’exemple ci-dessus sont exactement ce qui est nécessaire pour un test piloté par les données managées. Vous avez défini une propriété TestContext privée et fourni des valeurs getter et setter publiques pour que TAEF définisse les valeurs appropriées. À l’aide de la propriété TestContext privée, vous pouvez récupérer la valeur actuelle de l’une des propriétés de l’objet résultant de la requête WMI que vous avez récupérées à partir de TAEF.
Le code natif pour récupérer les propriétés WMI est très similaire. Comme avec les tests natifs pilotés par les données, vous allez utiliser TestData pour obtenir les valeurs de propriété. Par exemple, considérons le test d’obtention des propriétés de l’imprimante par défaut. Le fichier d’en-tête crée ce test comme suit :
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()
Pour cela, notre code de récupération, dans le fichier cpp se présente comme suit :
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 }
Prise en compte des valeurs de propriété NULL possibles
La partie à garder à l’esprit est que la requête WMI peut ne pas toujours retourner une propriété non null. Il peut arriver que la valeur de la propriété WMI retournée soit « null ». Si vous pensez que la propriété que vous recherchez peut être « null » dans certains scénarios, case activée pour elle avant de la vérifier ou d’essayer de l’utiliser.
Dans le code de test managé, par exemple, TestContext stocke les valeurs Null en tant qu’objet de type DBNull. Vous devez case activée si l’objet est de type DBNull avant d’essayer de convertir la valeur résultante en type attendu. Voyons voir :
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}
Par exemple, dans le test ci-dessus, « Compressed », « MaximumComponentLength » et « Availability » peuvent être null dans certains scénarios (lorsque la requête retourne des lecteurs amovibles comme des lecteurs de disquette). Vous souhaitez vous assurer que le test se comporte correctement dans de tels cas. À cette fin, récupérez la valeur de propriété en tant qu’objet et case activée si elle est de type « DBNull ». Si c’est le cas, cela signifie que la valeur de propriété retournée était null. Si ce n’est pas le cas, la valeur retournée n’était pas null et donc valide. Par conséquent, castez-la vers les types appropriés et utilisez-la pour le test.
Il en va de même pour les API de récupération natives : la valeur de propriété retournée peut être NULL. Cela signifie que vous devez case activée si TestData a correctement récupéré la valeur sans utiliser d’appel de vérification (car le fait de ne pas pouvoir récupérer peut être dû au fait que la valeur est null). Par exemple, vous pouvez avoir une méthode de test qui dépend d’une requête 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()
Vous pouvez avoir « Availability » et « MaximumComponentLength » retournés en tant que valeurs NULL. Écrivez donc le test pour tenir compte de ceci comme suit :
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 }