特集:UIオートメーションによる自動UIテストの実践

WindowsアプリのUIテストを自動化しよう

クロノス 亀野 弘嗣
2008/06/03
Page1 Page2 Page3

自動テストを実施するコード

Testメソッド(AddTwoItemメソッド内の処理)

 リスト2でTest属性が付けられているAddTwoItemメソッドは、実際のテスト内容が記述されたTestメソッドである。今回のサンプルでは、Testメソッドは1つしかないが、複数のテストを実施したい場合には、このようなTestメソッドを複数作成すればよい。

 AddTwoItemメソッドの内容を見ていこう。最初に次のようなコードがある。

AutomationElement txtInput = FindElement(aeForm, "txtInput");
AutomationElement btnAdd = FindElement(aeForm, "btnAdd");
AutomationElement lstResults = FindElement(aeForm, "lstResults");
リスト5 操作対象の各コントロールを取得するコード(AddTwoItemメソッドのコード内容)

 リスト5では、操作対象の各コントロール(txtInput、btnAdd、lstResults)への参照(AutomationElementオブジェクト)を、前述のFindElementメソッドを使用して取得している。FindElementメソッドでは、第1パラメータに指定した「aeForm」(=Windowsフォーム・アプリケーションのメイン・ウィンドウ)を検索のルート要素とし、第2パラメータにそれぞれのAutomationId値を指定している。AutomationIdの値としてはコントロールに付けた名前を使用する。

 その下に次のコードがある。

ValuePattern vpTxtInput =
  (ValuePattern)txtInput.GetCurrentPattern(ValuePattern.Pattern);
InvokePattern ipClickBtnAdd =
  (InvokePattern)btnAdd.GetCurrentPattern(InvokePattern.Pattern);
リスト6 操作対象のコントロール・パターンを取得するコード(AddTwoItemメソッドのコード内容)

 UIテストを行うにはコントロールを操作する必要がある。そこでこのリスト6のコードでは、各コントロールのAutomationElementオブジェクトから操作対象のコントロール・パターンを取得している。どのコントロール・パターンを取得するかは、操作内容によって決定する。

 ここでは、TextBoxコントロールについてはValuePatternコントロール・パターンを、ButtonコントロールについてはInvokePatternコントロール・パターンを使用する。それぞれのコントロール・パターンの内容については次の表を参照してほしい。

コントロール・パターン 説明
ValuePattern 値の取得または、設定を行う
InvokePattern ボタンなどを呼び出す
今回使用する2つのコントロール・パターン

 実際にAutomationElementオブジェクトからコントロール・パターンを取得するには、GetCurrnetPatternメソッドを使用する。パラメータにコントロール・パターンの識別子(「ValuePattern.Pattern」や「InvokePattern.Pattern」)を指定して呼び出せば、戻り値でコントロール・パターン・オブジェクト(=ValuePattern型やInvokePattern型のオブジェクト)が取得できる。なお、GetCurrnetPatternメソッドは戻り値がObject型で返されるため、実際の型(ValuePattern型やInvokePattern型)へのキャストが必要である。

 あとは、取得したコントロール・パターン・オブジェクト(=ValuePattern型やInvokePattern型のオブジェクト)を使って実際にコントロールをコードから操作する。それを行っているのが次のコードだ。

// 1つ目の値を入力、[追加]ボタン押下
vpTxtInput.SetValue("ねこ");
ipBtnAdd.Invoke();

// 2つ目の値を入力、[追加]ボタン押下
vpTxtInput.SetValue("いぬ");
ipBtnAdd.Invoke();
リスト7 コントロール・パターン・オブジェクトを使ってコントロールを操作するコード(AddTwoItemメソッドのコード内容)

 リスト7では、vpTxtInputコントロール・パターン・オブジェクトのSetValueメソッドを使用して、txtInputコントロール(TextBox)に「ねこ」という値を入力している。さらに、ipBtnAddコントロール・パターン・オブジェクトのInvokeメソッドを使用して、btnAddコントロール(Button)を自動的に押下している。

 2つ目の値「いぬ」に対しても同様の操作を行う。以上により、リストボックスに「ねこ」と「いぬ」という文字列が挿入されることになる。

AutomationElementCollection aecListItems =
    lstResults.FindAll(
      TreeScope.Children,
      new PropertyCondition(
        AutomationElement.ControlTypeProperty,
        ControlType.ListItem));
リスト8 リストボックスの値をすべて取得するコード(AddTwoItemメソッドのコード内容)

 続くリスト8では、リストボックスに設定された値を取得するため、リスト・アイテム(=リスト項目)の全要素を取得している。

 これを行うために、リストボックスのAutomationElementオブジェクト(lstResults)のFindAllメソッドを呼び出している。すでにFindFirstメソッドを使って1つの要素を取り出す方法を解説したが、条件に一致する要素をすべて取り出すにはFindAllメソッドを使用すればよい。

 FindAllメソッドの使用方法はFindFirstメソッドと同様で、第1パラメータに検索のスコープを指定し、第2パラメータに検索条件を指定する。ただし、FindFirstメソッドとは異なり、複数のAutomationElementオブジェクトが返されるため、戻り値はAutomationElementCollectionクラスのオブジェクトとなる。

 取得したAutomationElementCollectionオブジェクトから各AutomationElementオブジェクトにアクセスするには、AutomationElementCollectionの配列インデックスを使用する。

Assert.AreEqual(
  "ねこ", aecListItems[0].Current.Name, "1つ目の追加アイテム");
Assert.AreEqual(
  "いぬ", aecListItems[1].Current.Name, "2つ目の追加アイテム");
Assert.AreEqual(
  2, aecListItems.Count, "リストに追加されたアイテム数");
リスト9 リストボックスに追加された項目を検証するコード(AddTwoItemメソッドのコード内容)

 このリスト9では、NUnitのAssertクラスを使用して、リストボックスに追加されたアイテムと、アイテムの総数を検証している。

TearDownメソッド(TearDownメソッド内の処理)

 単体テストが終了する際に実行されるのがTearDownメソッドだ。今回のTearDownメソッドでは、テスト対象アプリケーションを終了させる。具体的には次のようなコード内容となっている。

WindowPattern wpForm =
  (WindowPattern)aeForm.GetCurrentPattern(WindowPattern.Pattern);
wpForm.Close();
リスト10 TearDownメソッドのコード内容

 リスト10では、フォームのAutomationElementオブジェクト(aeForm)からWindowPatternコントロール・パターン(wpForm)を取得する。これには、GetCurrentPatternメソッドのパラメータに「WindowPattern.Pattern」という識別子を指定すればよい。なお、WindowPatternは、ウィンドウを閉じたりするためのコントロール・パターンだ。

 最後に、いま取得したwpFormコントロール・パターン・オブジェクトのCloseメソッドでウィンドウを閉じてアプリケーションを終了させる。

 以上が今回のテスト・プログラムの全内容である。それでは実際にテストを実施してみよう。

テストの実施

 テストの実施方法は、NUnitのGUIツール(以下、NUnit GUI)の通常の使用方法でよい(NUnitの操作については「テスト駆動開発ツール最前線」を参考にされたい)。

 NUnit GUIを起動し、メニュー・バーから[File]−[Open Project]を選択し、ファイル選択ダイアログが表示されたら、作成したテスト・クラスをコンパイルして生成された.DLLファイルを指定する。NUnit GUIにテストがロードされるので、今回のテスト・メソッド「AddTwoItem」を選択して、[Run]ボタンを押下する。これによりテストが開始される。

 アプリケーションが終了すると、NUnit GUIにテスト結果が表示される。

UIオートメーションを実際に活用する際のポイント

 本稿では、単一の簡単なテスト・ケースのテストにとどめたが、実際の開発では、大量のテスト・ケースを扱うことになるはずなので、テスト・ケースの外部ファイル化など効率化する必要がある。

 また今回は、.NET Windowsフォーム・アプリケーションのUIテストについて説明したが、UIオートメーションは、WPFアプリケーションでも利用可能である。その場合は、System.Windows.Automation.Peers名前空間を利用してテスト・クラスを作成すればよい。

まとめ

 以上、UIオートメーションを活用したUIテストの自動化を簡単なサンプルを使って説明した。

 このようにUIオートメーションを使用することで、ツリー構造でコントロールを扱えたり、コントロール型とコントロール・パターンによりコントロールのUI操作をオブジェクト指向で扱えたりするなど、一貫性のあるテスト・コードが作成できる。

 UIオートメーションは、ほかのテスティング・フレームワークとは異なり、.NET Frameworkに標準で用意されているので、特別なインストールなしで利用できるため、今後、より利用される機会が増えるだろう。End of Article

 

 INDEX
  [特集] UIオートメーションによる自動UIテストの実践
  WindowsアプリのUIテストを自動化しよう
    1. UI オートメーションとは? サンプル・アプリについて
    2. テスト・クラスの作成と、コードの解説
  3. 自動テストを実施するコードと、その実施


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間