Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Por favor, certifique-se de que você está familiarizado com a execução básica do TAEF e sabe como criar testes usando-o, antes de prosseguir com esta seção.
Contexto geral
"WMI" significa "Instrumentação de Gerenciamento do Windows". Usando o Common Information Model (CIM), que é o padrão da indústria para representar sistemas. A Instrumentação de Gerenciamento do Windows fornece uma maneira unificada de acessar informações de gerenciamento do sistema.
Como é que ajuda os meus testes?
Usando o suporte à consulta WMI disponível como a Fonte de Dados WMI no TAEF, você pode adicionar uma pré-condição ao teste, bem como obter informações sobre os recursos na máquina de teste antes de executar o teste. Aqui estão alguns dos exemplos do tipo de consulta que você pode fazer usando WMI:
- Verifique se a máquina em que o teste está sendo executado é um laptop e execute o teste somente se for um laptop.
- Verifique se um service pack foi instalado na máquina de teste e execute o teste somente se tiver sido.
- Recupere todas as unidades removíveis e unidades de disco rígido locais na máquina de teste e execute o teste para cada uma das unidades que correspondem à consulta.
- Execute o teste somente se a máquina de teste não estiver associada ao domínio OU
- Execute o teste somente se a máquina de teste estiver associada ao domínio e recuperar o nome de domínio.
Espera-se que isso tenha lhe dado alguma ideia sobre onde e como você pode aproveitar a fonte de dados WMI para seus testes. Vamos ver como adicionar esse suporte à consulta WMI durante a criação de um teste TAEF.
Os únicos metadados especiais que você precisa para tornar seu teste um teste WMI DataSource é o "DataSource". A sintaxe DataSource deve ter a seguinte aparência:
[DataSource("WMI:<WQL query>")]
Ou em código nativo:
TEST_METHOD_PROPERTY(L"DataSource", L"WMI:<WQL query>")]
Você deve ter notado que o valor DataSource começa com "WMI:", o que permite que o TAEF saiba que essa é realmente a fonte de dados para um teste que depende do resultado da consulta WMI e também o distingue do teste controlado por dados. Esta é uma boa oportunidade para mencionar que, atualmente, o TAEF não suporta que um teste seja ao mesmo tempo orientado por dados e dependa do resultado da consulta WMI.
A próxima pergunta naturalmente é como escrever consultas WQL para o que você está procurando? A sintaxe da consulta WQL é muito semelhante às consultas SQL simplificadas. Existem alguns exemplos muito bons de consultas fornecidas em Tarefas WMI para scripts e aplicativos. Eis alguns exemplos:
SELECT Descrição, DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'
Execute o teste no serviço "Temas" depois de descobrir as propriedades Description, DesktopInteract e ProcessId que você pretende usar em seu teste.
SELECT Capacidades, CapacidadeDescrições DE Win32_Printe
Execute o teste para cada impressora conectada a este computador. Permita que o teste aceda às Capacidades e Descrições de Capacidades de cada impressora.
SELECT Nome, Utilizador, Localização de Win32_StartupCommand
Execute o teste para cada processo que é executado na inicialização do Windows. Para cada processo, deixe o teste saber qual é o Nome do processo, onde ele está localizado (Local) e como Usuário o processo é executado.
Você pode encontrar mais exemplos na documentação mencionada acima, bem como no arquivo .cs e no arquivo de cabeçalho nos exemplos que você abriu. A sintaxe geral e excessivamente simplificada é a seguinte:
SELECT <comma separated properties> FROM <WMI Class name> [WHERE <add condition on some properties>]
Nos exemplos que você acabou de ver, Win32_Service, Win32_Printer e Win32_StartupCommand são todas classes WMI. Você pode procurar as classes WMI em classes WMI.
O TAEF não suporta a recuperação de Propriedades do Sistema.
Nos bastidores, o TAEF executará a consulta para você e confirmará o resultado. Se pelo menos um objeto for retornado como resultado da consulta, o teste será executado para cada objeto retornado. Se a consulta WQL não retornar nenhum objeto, o teste será registrado como Bloqueado com essas informações e a execução passará para o próximo teste.
Verificar ou verificar sua consulta antes de criar seu teste parece ser uma ótima ideia, e é um processo muito simples:
- A partir da caixa de diálogo de execução ou de um prompt de comando, invoque "wbemtest.exe"
- Clique no botão "Conectar" no canto superior direito.
- Verifique se seu namespace é "root\cimv2" antes de clicar em "Conectar" novamente no canto superior direito.
- Em "IWbemServices", clique em "Consulta"
- Introduza a sua consulta na caixa de edição que aparece e clique em "Aplicar"
NOTA: O "IWbemService" tem várias outras opções que podem ajudá-lo com a sua consulta. Por exemplo, utilizar "Enum Classes" e alterar o botão rádio para "recursivo" irá ajudá-lo a ver todas as classes WMI no sistema.
Recuperando propriedades consultadas usando a consulta WMI
Agora você já tem uma idéia de como criar uma consulta WMI para um método de teste e como aplicá-lo como metadados durante a criação de um teste. Você também sabe como confirmar se a consulta é válida usando wbemtest.exe. Agora vamos ver como recuperar os valores de propriedade que você estava procurando.
As noções básicas sobre como recuperar essas informações são muito semelhantes à recuperação de valores para seu teste orientado por dados. Por exemplo, no código gerenciado, isso seria parecido com o seguinte:
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}
As linhas 24-30 no exemplo acima são exatamente o que é necessário para um teste controlado por dados gerenciados. Você definiu uma propriedade TestContext privada e forneceu getter e setter público nela para que o TAEF definisse os valores corretos. Usando a propriedade privada TestContext, você pode recuperar o valor atual para qualquer uma das propriedades do objeto resultante da consulta WMI que você recuperou do TAEF.
O código nativo para recuperar as propriedades WMI é muito semelhante. Como nos testes controlados por dados nativos, você usará TestData para obter os valores de propriedade. Por exemplo, vamos considerar o teste para obter propriedades da impressora padrão. O arquivo de cabeçalho cria este teste assim:
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()
Para isso, nosso código de recuperação, no arquivo cpp tem a seguinte aparência:
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 }
Considerando possíveis valores de propriedade NULL
O que se deve ter em mente é que a consulta WMI nem sempre pode retornar uma propriedade não nula. Pode haver vezes em que o valor da propriedade WMI retornado é "nulo". Se achar que a propriedade que está a procurar pode ser nula em alguns cenários, então verifique antes de confirmá-la ou tentar utilizá-la.
No código de teste gerenciado, por exemplo, TestContext armazenará os valores nulos como um objeto do tipo DBNull. Você deve verificar se o objeto é do tipo DBNull antes de tentar converter o valor resultante para o tipo que você espera que seja. Vejamos:
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}
Por exemplo, no teste acima, "Compressed", "MaximumComponentLength" e "Availability" podem ser nulos em alguns cenários (quando a consulta retorna unidades removíveis, como unidades de disquete). Deve certificar-se de que o teste se comporta adequadamente nesses casos. Para esse fim, recupere o valor da propriedade como um objeto e verifique se ele é do tipo "DBNull". Se for, significa que o valor da propriedade retornado foi nulo. Se não for, o valor retornado não foi nulo e, por conseguinte, é válido - então converta-o para os tipos apropriados e use-o para o teste.
O mesmo é verdadeiro com APIs de recuperações nativas também - o valor da propriedade retornada pode ser NULL. Isso significa que você precisa verificar se o TestData recuperou com êxito o valor sem usar uma chamada de verificação (já que não ser capaz de recuperar pode ser porque o valor é nulo). Por exemplo, você pode ter um método de teste que depende de uma consulta 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()
Você pode ter "Availability e "MaximumComponentLength" retornados como valores NULL. Então, escreva o teste para explicar isso assim:
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 }