コントロールのコード化された UI テストの有効化
目的のコントロールが、コード化された UI テスト フレームワークがのサポートを実装すると、より簡単にテストできます。サポートの増加するレベルをインクリメント方式で追加できます。レコードおよび再生およびプロパティの検証をサポートします。これで、コード化された UI テスト ビルダーは、コントロールのカスタム プロパティを確認できるように、ビルドし、生成されたコードからそれらのプロパティにアクセスするためのカスタム クラスを提供します。また、コード化された UI テスト ビルダーが記録されるアクションの意図に近い方法でアクションをキャプチャすることができます。
このトピックの内容
アクセシビリティを実行してレコードおよび再生およびプロパティの検証をサポートします。
コード化された UI テスト ビルダー]で記録時に検出し、そのセッションを再生するコードを生成するコントロールに関する情報をキャプチャします。は、コントロールがユーザー補助をサポートしていない場合、コード化された UI テスト ビルダーは画面座標を使用してアクション (マウス クリックなど) キャプチャ。テストした場合、生成されるコードは同じ画面座標でのマウス クリックが発行されます。テストした場合は、コントロールが画面上の別の場所にある場合は、生成されたコードは、コントロールのそのアクションを実行しません。これは失敗で、テストが異なる画面の構成で、さまざまな環境で場合、または UI のレイアウトが変更された後に発生する可能性があります。
テストを記録し、コードを生成するときアクセシビリティを実行すると、では、コントロールに関する情報を取り込むために、コード化された UI テスト ビルダーで使用するあります。次に、テストを実行すると、生成されたコードは、コントロールに対してユーザー インターフェイスのどこかでも、それらのイベントを再生します。テストの作成者は、コントロールの基本的なプロパティを使用して、Assert 作成します。
Windows フォーム コントロールの記録と再生、プロパティの検証とナビゲーション サポートする
次のプロシージャである、コントロールのアクセシビリティを、AccessibleObjectで詳しく説明する実装します。
Control.ControlAccessibleObject実装から派生し、クラスのオブジェクトを返すに AccessibilityObject のプロパティをオーバーライドしてクラスを示しています。
public partial class ChartControl : UserControl { // Overridden to return the custom AccessibleObject for the control. protected override AccessibleObject CreateAccessibilityInstance() { return new ChartControlAccessibleObject(this); } // Inner class ChartControlAccessibleObject represents accessible information // associated with the ChartControl and is used when recording tests. public class ChartControlAccessibleObject : ControlAccessibleObject { ChartControl myControl; public ChartControlAccessibleObject(ChartControl ctrl) : base(ctrl) { myControl = ctrl; } } }
アクセスできるオブジェクトの Role、State、GetChild と GetChildCount のプロパティおよびメソッドをオーバーライドします。
子コントロールの異なるアクセシビリティのオブジェクトを実装して返すために子コントロールの AccessibilityObject のプロパティとアクセシビリティのオブジェクトをオーバーライドします。
子コントロールのアクセシビリティのオブジェクトの Bounds、Name、Parent、Role、State、Navigateと Select のプロパティおよびメソッドをオーバーライドします。
[!メモ]
この手順の AccessibleObject のアクセシビリティのサンプルで始まり、このトピックの残りの手順の観点で、組み込まれます。アクセシビリティの例の作業バージョンを作成する場合は、コンソール アプリケーションを作成し、サンプル コードで Program.cs のコードに置き換えます。ユーザー補助、System.Drawing、System.Windows.Forms への参照を追加する必要があります。[ビルド警告を除去するには、アクセシビリティの [相互運用機能型の埋め込み] を変更する必要があります。アプリケーションを実行すると、コンソール ウィンドウが表示されないように Windows アプリケーションとコンソール アプリケーションからにプロジェクトの出力の種類を変更できます。
プロパティ プロバイダーの実装によってカスタム プロパティの検証をサポートします。
レコードおよび再生およびプロパティの検証の基本的なサポートを実装する場合は、コントロールのカスタム プロパティを UITestPropertyProvider プラグインを実行して、コード化された UI テストに使用できるようにする。たとえば、次の手順では、コード化された UI テストがグラフ コントロールの CurveLegend の子コントロールの状態プロパティにアクセスできるようにするプロパティ プロバイダーを作成します。
カスタム プロパティの検証をサポートします。
複数のプロパティを実装している場合は、セミコロンを主要な説明 (およびその) で区切って説明文字列のさまざまなプロパティ値を渡すに曲線の凡例でアクセスできるオブジェクトの Description のプロパティをオーバーライドします (;)。
public class CurveLegendAccessibleObject : AccessibleObject { // add the state property value to the description public override string Description { get { // Add “;” and the state value to the end // of the curve legend’s description return "CurveLegend; " + State.ToString(); } } }
コントロールに対する UI テストの拡張機能のパッケージをクラス ライブラリ プロジェクトの作成、ユーザー補助、Microsoft.VisualStudio.TestTools.UITesting、Microsoft.VisualStudio.TestTools.UITest.Common と Microsoft.VisualStudio.TestTools.Extension への参照を追加します。[ユーザー補助の [相互運用機能型の埋め込み] を変更します。
UITestPropertyProviderから派生したプロパティのプロバイダー クラスを追加します。
using System; using System.Collections.Generic; using Accessibility; using Microsoft.VisualStudio.TestTools.UITesting; using Microsoft.VisualStudio.TestTools.UITest.Extension; using Microsoft.VisualStudio.TestTools.UITesting.WinControls; using Microsoft.VisualStudio.TestTools.UITest.Common; namespace ChartControlExtensionPackage { public class ChartControlPropertyProvider : UITestPropertyProvider { } }
Dictionary<TKey, TValue>にプロパティ名とプロパティ記述子を設定することによってプロパティ プロバイダーを実装します。
// Define a map of property descriptors for CurveLegend private static Dictionary<string, UITestPropertyDescriptor> curveLegendPropertiesMap = null; private static Dictionary<string, UITestPropertyDescriptor> CurveLegendPropertiesMap { get { if (curveLegendPropertiesMap == null) { UITestPropertyAttributes read = UITestPropertyAttributes.Readable | UITestPropertyAttributes.DoNotGenerateProperties; curveLegendPropertiesMap = new Dictionary<string, UITestPropertyDescriptor> (StringComparer.OrdinalIgnoreCase); curveLegendPropertiesMap.Add("State", new UITestPropertyDescriptor(typeof(string), read)); } return curveLegendPropertiesMap; } } // return the property descriptor public override UITestPropertyDescriptor GetPropertyDescriptor(UITestControl uiTestControl, string propertyName) { return CurveLegendPropertiesMap[propertyName]; } // return the property names public override ICollection<string> GetPropertyNames(UITestControl uiTestControl) { if (uiTestControl.ControlType.NameEquals("Chart") || uiTestControl.ControlType.NameEquals("Text")) { // the keys of the property map are the collection of property names return CurveLegendPropertiesMap.Keys; } // this is not my control throw new NotSupportedException(); } // Get the property value by parsing the accessible description public override object GetPropertyValue(UITestControl uiTestControl, string propertyName) { if (String.Equals(propertyName, "State", StringComparison.OrdinalIgnoreCase)) { object[] native = uiTestControl.NativeElement as object[]; IAccessible acc = native[0] as IAccessible; string[] descriptionTokens = acc.accDescription.Split(new char[] { ';' }); return descriptionTokens[1]; } // this is not my control throw new NotSupportedException(); }
作成するアセンブリが、コントロールとその子コントロールに固有のサポートを提供することを示すために UITestPropertyProvider.GetControlSupportLevel をオーバーライドします。
public override int GetControlSupportLevel(UITestControl uiTestControl) { // For MSAA, check the control type if (string.Equals(uiTestControl.TechnologyName, "MSAA", StringComparison.OrdinalIgnoreCase) && (uiTestControl.ControlType == "Chart"||uiTestControl.ControlType == "Text")) { return (int)ControlSupport.ControlSpecificSupport; } // This is not my control, so return NoSupport return (int)ControlSupport.NoSupport; }
Microsoft.VisualStudio.TestTools.UITesting.UITestPropertyProviderの残りの抽象メソッドをオーバーライドします。
public override string[] GetPredefinedSearchProperties(Type specializedClass) { throw new NotImplementedException(); } public override Type GetSpecializedClass(UITestControl uiTestControl) { throw new NotImplementedException(); } public override Type GetPropertyNamesClassType(UITestControl uiTestControl) { throw new NotImplementedException(); } public override void SetPropertyValue(UITestControl uiTestControl, string propertyName, object value) { throw new NotImplementedException(); } public override string GetPropertyForAction(UITestControl uiTestControl, UITestAction action) { throw new NotImplementedException(); } public override string[] GetPropertyForControlState(UITestControl uiTestControl, ControlStates uiState, out bool[] stateValues) { throw new NotImplementedException(); }
UITestExtensionPackageから派生した拡張パッケージ クラスを追加します。
using System; using Microsoft.VisualStudio.TestTools.UITesting; using Microsoft.VisualStudio.TestTools.UITest.Extension; using Microsoft.VisualStudio.TestTools.UITest.Common; namespace ChartControlExtensionPackage { internal class ChartControlExtensionPackage : UITestExtensionPackage { } }
アセンブリの UITestExtensionPackage の属性を定義します。
[assembly: Microsoft.VisualStudio.TestTools.UITest.Extension.UITestExtensionPackage( "ChartControlExtensionPackage", typeof(ChartControlExtensionPackage.ChartControlExtensionPackage))] namespace ChartControlExtensionPackage { …
拡張パッケージ クラスでは、プロパティ プロバイダーが要求されたときにプロパティ プロバイダー クラスを返すオーバーライド UITestExtensionPackage.GetService。
internal class ChartControlExtensionPackage : UITestExtensionPackage { public override object GetService(Type serviceType) { if (serviceType == typeof(UITestPropertyProvider)) { if (propertyProvider == null) { propertyProvider = new ChartControlPropertyProvider(); } return propertyProvider; } return null; } private UITestPropertyProvider propertyProvider = null; }
UITestExtensionPackageの残りの抽象メソッドとプロパティをオーバーライドします。
public override void Dispose() { } public override string PackageDescription { get { return "Supports coded UI testing of ChartControl"; } } public override string PackageName { get { return "ChartControl Test Extension"; } } public override string PackageVendor { get { return "Microsoft (sample)"; } } public override Version PackageVersion { get { return new Version(1, 0); } } public override Version VSVersion { get { return new Version(10, 0); } }
は、binary をビルドして %ProgramFiles%\Common\Microsoft Shared\VSTT\10.0\UITestExtensionPackagesにコピーします。
[!メモ]
この拡張機能パッケージは型 "Text" であるすべてのコントロールに適用されます。同じ型の複数のコントロールをテストする場合、テストを記録すると、拡張子のパッケージが配置されるそれぞれをテストし、管理する必要があります。
クラスのカスタム プロパティにアクセスするために実行するとコード生成をサポートします。
コード化された UI テスト ビルダーがセッションの記録からコードを生成すると、コントロール内にアクセスするには UITestControl クラスを使用します。
UITestControl uIAText = this.UIItemWindow.UIChartControlWindow.UIAText;
Assert.AreEqual(this.AssertMethod3ExpectedValues.UIATextState, uIAText.GetProperty("State").ToString());
コントロールのカスタム プロパティへのアクセスを提供するプロパティ プロバイダーを実装する場合、生成されたコードを簡単になるように、これらのプロパティへのアクセスに使用される特別なクラスを追加できます。
ControlLegend uIAText = this.UIItemWindow.UIChartControlWindow.UIAText;
Assert.AreEqual(this.AssertMethod3ExpectedValues.UIATextState, uIAText.State);
特殊なクラスを、コントロールにアクセスするには
から派生した WinControl 実行し、コンストラクターの検索プロパティのコレクションにコントロールの型をクラスに追加します。
public class CurveLegend:WinControl { public CurveLegend(UITestControl c) : base(c) { // The curve legend control is a “text” type of control SearchProperties.Add( UITestControl.PropertyNames.ControlType, "Text"); } }
クラスのプロパティとして、コントロールのカスタム プロパティを実装します。
public virtual string State { get { return (string)GetProperty("State"); } }
曲線の凡例の子コントロールの新しいクラスの型を返すためのプロパティ プロバイダーの UITestPropertyProvider.GetSpecializedClass のメソッドをオーバーライドします。
public override Type GetSpecializedClass(UITestControl uiTestControl) { if (uiTestControl.ControlType.NameEquals("Text")) { // This is text type of control. For my control, // that means it’s a curve legend control. return typeof(CurveLegend); } // this is not a curve legend control return null; }
新しいクラスの PropertyNames のメソッドの型を返すためのプロパティ プロバイダーの GetPropertyNamesClassType のメソッドをオーバーライドします。
public override Type GetPropertyNamesClassType(UITestControl uiTestControl) { if (uiTestControl.ControlType.NameEquals("Text")) { // This is text type of control. For my control, // that means it’s a curve legend control. return typeof(CurveLegend.PropertyNames); } // this is not a curve legend control return null; }
アクション フィルターの実装によって意図を認識する操作をサポートします。
Visual Studio は、テストを記録すると、各マウス イベントとキーボード イベントのキャプチャ。ただし、アクションの目的は、一連のマウス イベントとキーボードで失われる可能性があります。たとえば、コントロールが autocomplete をサポートする場合は、マウスとキーボード イベントのセットは別の値でテストを別の環境でされると発生する場合があります。一つのアクションと一連のキーボード イベントおよびマウス イベントを置き換えるアクション フィルターのプラグインを追加できます。この方法で、値を設定する一つのアクションと値を選択してその一連のマウス イベントとキーボード イベントを置き換えることができます。そのすると、1 個の環境から別の場所に autocomplete の相違点からコード化された UI テストを保護します。
意図を認識する操作をサポートできます。
プロパティ ApplyTimeout、Category、Enabled、FilterType、Group と Nameをオーバーライド UITestActionFilterから派生したアクション フィルターのクラスを実装します。
internal class MyActionFilter : UITestActionFilter { // If the user actions we are aggregating exceeds the time allowed, // this filter is not applied. (The timeout is configured when the // test is run.) public override bool ApplyTimeout { get { return true; } } // Gets the category of this filter. Categories of filters // are applied in priority order. public override UITestActionFilterCategory Category { get { return UITestActionFilterCategory.PostSimpleToCompoundActionConversion; } } public override bool Enabled { get { return true; } } public override UITestActionFilterType FilterType { // This action filter operates on a single action get { return UITestActionFilterType.Unary; } } // Gets the name of the group to which this filter belongs. // A group can be enabled/disabled using configuration file. public override string Group { get { return "ChartControlActionFilters"; } } // Gets the name of this filter. public override string Name { get { return "Convert Double-Click to Single-Click"; } }
ProcessRule をオーバーライドします。次の例の realpces シングルクリックのアクションでダブルクリック アクション。
public override bool ProcessRule(IUITestActionStack actionStack) { if (actionStack.Count > 0) { MouseAction lastAction = actionStack.Peek() as MouseAction; if (lastAction != null) { if (lastAction.UIElement.ControlTypeName.Equals( ControlType.Text.ToString(), StringComparison.OrdinalIgnoreCase)) { if(lastAction.ActionType == MouseActionType.DoubleClick) { // Convert to single click lastAction.ActionType = MouseActionType.Click; } } } } // Do not stop aggregation return false; }
拡張機能のパッケージの GetService のメソッドにアクション フィルターを追加します。
public override object GetService(Type serviceType) { if (serviceType == typeof(UITestPropertyProvider)) { if (propertyProvider == null) { propertyProvider = new PropertyProvider(); } return propertyProvider; } else if (serviceType == typeof(UITestActionFilter)) { if (actionFilter == null) { actionFilter = new RadGridViewActionFilter(); } return actionFilter; } return null; }
は、binary をビルドして\Common Files\Microsoft Shared\VSTT\10.0\UITestExtensionPackages に %ProgramFiles%コピーします。
[!メモ]
アクション フィルターは、ユーザー補助の実装またはプロパティ プロバイダーに依存しません。
プロパティ プロバイダー、またはアクション フィルターのデバッグ
、プロパティ プロバイダー、およびアクション フィルターは、アプリケーションとは別のプロセスでコード化された UI テスト ビルダーによって、読み込まれて実行される拡張パッケージで実装されます。
プロパティ プロバイダー、またはアクションをデバッグするには、フィルター処理
\Common Files\Microsoft Shared\VSTT\10.0\UITestExtensionPackages に %ProgramFiles%、拡張機能のパッケージのコピーのデバッグ バージョンを .pdb ファイルと .dll をビルドします。
アプリケーションを実行します (デバッガーでない)。
コード化された UI テスト ビルダーを実行します。
codedUITestBuilder.exe /standalone
codedUITestBuilder プロセスにデバッガーをアタッチします。
コードのブレークポイントを設定します。
コード化された UI テスト ビルダーでアクションを実行するためのプロパティ プロバイダー、およびレコードのアクションを実行するために ASSERT フィルター処理作成します。
外部リソース
ガイダンス
Visual Studio 2012 –の章の 2 番目の一連の配信のためのテスト: 単体テスト: 内部のテスト