次の方法で共有


WMI データ ソース

このセクションに進む前に、TAEF の基本的な実行に慣れ、それを使用してテストを作成する方法を理解していることを確認してください。

バックグラウンド

"WMI" は "Windows Management Instrumentation" の略です。 システムを表す業界標準である共通情報モデル (CIM) の使用。 Windows Management Instrumentation は、システム管理情報にアクセスするための統合された方法を提供します。

テストにどのように役立ちますか?

TAEF の WMI DataSource として使用可能な WMI クエリ サポートを使用すると、テストを実行する前に、テストに前提条件を追加したり、テスト コンピューター上のリソースに関する情報を取得したりできます。 WMI を使用して実行できるクエリの種類の例を次に示します。

  • テストが実行されているコンピューターがノート PC であるかどうかを確認し、テストがノート PC の場合にのみ実行します。
  • テストマシンにサービスパックがインストールされているかどうかを確認し、インストールされている場合にのみテストを実行します。
  • テスト マシン上のすべてのリムーバブル ドライブとローカル ハード ディスク ドライブを取得し、クエリに一致する各ドライブのテストを実行します。
  • テスト マシンがドメインに参加していない場合のみ、テストを実行します。
  • テスト マシンがドメインに参加している場合にのみテストを実行し、ドメイン名を取得します。

これで、テストに WMI DataSource を活用できる場所と方法について、いくつかのアイデアが得られれば幸いです。 TAEF テストの作成時に、この WMI クエリサポートを追加する方法を見てみましょう。

テストを WMI DataSource テストにするために必要な唯一の特別なメタデータは、"DataSource" です。 DataSource 構文は次のようになります。

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

または、ネイティブ コードで次の手順を実行します。

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

DataSource の値が "WMI:" で始まることに注意する必要があります。これにより、これが実際に WMI クエリの結果に依存し、データ ドリブン テストと区別されるテストのデータ ソースであることが TAEF に認識されます。 これは、現在、TAEF では、データ ドリブン テストと WMI クエリ結果に依存するテストの両方のテストをサポートしていないことに言及する良い機会です。

次の質問は、探しているものに対して WQL クエリを記述する方法です。 WQL クエリ構文は、簡略化された SQL クエリによく似ています。 スクリプトとアプリケーションの WMI タスクで提供されるクエリの非常に良い例がいくつかあります。 次に例をいくつか示します。

SELECT Description,DesktopInteract, ProcessId FROM Win32_Service WHERE Name='Themes'
テストで使用する Description、DesktopInteract、ProcessId プロパティを見つけた後、"テーマ" サービスでテストを実行します。

SELECT Capabilities,CapabilityDescriptions FROM Win32_Printe
このコンピューターに接続されているプリンターごとにテストを実行します。 テストで各プリンターの Capabilities と CapabilityDescription にアクセスできるようにします。

SELECT Name、User、Location FROM Win32_StartupCommand
Windows の起動時に実行される各プロセスのテストを実行します。 各プロセスについて、プロセスの名前、プロセスの場所 (場所)、プロセスが実行されるユーザーをテストに通知します。

上記のドキュメントのほか、開いた例の.cs ファイルとヘッダー ファイルにも、その他の例があります。 一般的な、単純化された構文は次のとおりです。

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

今見た例では、Win32_Service、Win32_Printer、Win32_StartupCommandはすべて WMI クラスです。 WMI クラスで WMI クラスを検索できます。

TAEF では、システム プロパティの取得はサポートされていません。

バックグラウンドで TAEF によってクエリが実行され、結果が確認されます。 クエリの結果として少なくとも 1 つのオブジェクトが返された場合、返されたオブジェクトごとにテストが実行されます。 WQL クエリがオブジェクトを返さない場合、テストはこの情報で Blocked としてログに記録され、実行は次のテストに進みます。

テストを作成する前にクエリを確認または確認することは、非常に簡単なプロセスです。

  • 実行ダイアログまたはコマンド プロンプトから "wbemtest.exe" を呼び出す
  • 右上隅にある [接続] ボタンをクリックします。
  • 右上隅の [接続] をもう一度クリックする前に、名前空間が "root\cimv2" であることを確認します。
  • [IWbemServices] の [クエリ] をクリックします。
  • 表示される編集ボックスにクエリを入力し、[適用] をクリックします

注: "IWbemService" には、クエリに役立つ他のいくつかのオプションがあります。 たとえば、"Enum Classes" を使用し、ラジオ ボタンを "recursive" に変更すると、システム上のすべての WMI クラスが表示されます。

WMI クエリを使用してクエリを実行したプロパティの取得

ここまでで、テスト メソッドの WMI クエリを作成する方法と、テストの作成時にメタデータとして適用する方法について説明しました。 また、wbemtest.exeを使用してクエリが有効であることを確認する方法についても説明します。 次に、探していたプロパティ値を取得する方法を見てみましょう。

この情報の取得の基本は、データ ドリブン テストの値の取得とよく似ています。 たとえば、マネージド コードでは、これは次のようになります。

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}

上の例の 24 から 30 行目は、マネージド データ ドリブン テストに必要です。 TAEF が適切な値を設定できるように、プライベート TestContext プロパティを定義し、パブリック ゲッターとセッターを指定しました。 プライベート TestContext プロパティを使用すると、TAEF から取得した WMI クエリ結果オブジェクトのプロパティの現在の値を取得できます。

WMI プロパティを取得するためのネイティブ コードは非常によく似ています。 ネイティブ データドリブン テストと同様に、TestData を使用してプロパティ値を取得します。 たとえば、既定のプリンターのプロパティを取得するためのテストについて考えてみましょう。 ヘッダー ファイルは、次のようにこのテストを作成します。

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

このため、cpp ファイル内の取得コードは次のようになります。

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    }

可能な NULL プロパティ値を計算する

注意すべき点は、WMI クエリが常に null 以外のプロパティを返すわけではないという点です。 返される WMI プロパティ値が "null" の場合があります。 探しているプロパティが一部のシナリオで "null" である可能性があると思われる場合は、それを確認するか、使用する前に確認してください。

たとえば、マネージド テスト コードでは、TestContext は NULL 値を DBNull 型のオブジェクトとして格納します。 結果の値を想定した型にキャストする前に、オブジェクトが DBNull 型であるかどうかを確認する必要があります。 見てみましょう。

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}

たとえば、上記のテストでは、一部のシナリオで "Compressed"、"MaximumComponentLength"、"Availability" が null になることがあります (クエリがフロッピー ドライブなどのリムーバブル ドライブを返す場合)。 このような場合は、テストが適切に動作することを確認する必要があります。 この最後に、プロパティ値をオブジェクトとして取得し、それが "DBNull" 型であるかどうかを確認します。 その場合は、返されたプロパティ値が null であることを意味します。 そうでない場合、返された値は null ではなく、有効であるため、適切な型にキャストし、テストに使用します。

ネイティブ取得 API でも同様です。返されるプロパティ値は NULL になる可能性があります。 これは、TestData が検証呼び出しを使用せずに値を正常に取得したかどうかを確認する必要があることを意味します (取得できないのは、値が null である可能性があるためです)。 たとえば、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()

"Availability and "MaximumComponentLength" が NULL 値として返される場合があります。 そのため、次のようにテストを記述します。

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    }