Activer le test codé de l'interface utilisateur de vos contrôles
Votre controle peut être testé plus facilement si vous implementez le support pour le framework pour tests codés de l'interface utilisateurs.Vous pouvez ajouter des niveaux croissant de support en incrémentant.Vous pouvez commencez par supporté les validations de propriétés enregistrer et lecture.Vous pouvez construire la dessus pour permettre au constructure de test codé de l'interface utilisateur pour reconnâitre les propriétés customisé de vos contrôles, et fournir des classes personalisées à partir de code générer.Vous pouvez aussi aider les actions de capture du constructeur de test codé de l'interface d'une manière qui est proche du but de l'action entrain d'être enregistré.
Dans cette rubrique :
Le support de validation de propriétés personalisés en implémentant un Fournisseur de propriété.
Le support de génération de code en implémentant une class pour accéder au propriétés personalisées.
Le support des actions d'Intent-Aware avec l'implementation d'un filtre d'action.
Le support de l'enregistrement et de lecture et validation de propriétés sont implémentant avec L'Accesibilité.
Le constructeur de test codé de l'interface utilisateur capture des informations à propos des contrôles qu'il rencontre pendant un enregistrement puis génére le code pour rejouer cette session.Si votre contrôle ne supporte pas l'accéssibilité, alors le constructeur de tests de codés de l'interface utilisateur capturera des actions (tels que les cliques de souris) en utilisé des coordonnées de l'écran.Lors que le test est rejoué, le code générer effectuera des cliques de souris dans les même coordonnées de l'écran.Si votre contrôle s'affiche dans un endroit différent de l'écran quand le test est rejouer, le code générer échouera à l'éxécution de l'action effectué sur le contrôle.Ceci peux résulter dans les échecs si le test est réjoué sur des configurations d'écran différentes, dans des environnements différents, ou après des changements dans la disposition de votre interface utilisateur.
Si vous implementez l'accéssibilité, le constructeur de tests de codés de l'interface utilisateur utilisera celui-ci pour capturer des informations à propos de votre contrôle lorsqu'il enregistre un test et génere le code.Dès alors, lorsque vous éxécutez le test, le code générer rejouera ces événements sur vontre contrôle, même si il est quelque part d'autre dans l'interface utilisateur.Les auteurs des tests pourront également créer des affirmations en utilisant les propriétés basics de votre contrôle.
Pour supporter l'enregistrement et la lecture, la validation de propriétés et la navation pour un contrôle Windows Forms.
L'Implementation de l'accéssibilité pour vontre contrôle est delimité à travers les procédures suivantes, et expliqué en détaille dans AccessibleObject.
L'implémentation d'une classe qui dérive de Control.ControlAccessibleObject et surcharge la propriété AccessibilityObject pour retourner un objet de votre classe.
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; } } }
La surcharge les propriétés et méthodes accésibles Role, State, GetChild et GetChildCount de l'objet.
L'implementation d'un autre object d'accéssibilité pour le contrôle enfant et surcharge la propriété du contrôle enfant AccessibilityObject, celui-ci retourne un objet d'accéssibilité.
La surcharge les propriétés et méthodes Bounds, Name, Parent, Role, State, Navigate et Select pour l'objet d'accéssibilité du contrôle enfant.
[!REMARQUE]
Cette rubrique commence avec l'example d'accéssibilité dans AccessibleObject dans cette procédure, et ensuite construit les procédures restants.Si vous souhaitez crée une version fonctionnelle de l'example d'accéssibilité, créer une application console et ensuite remplacé le code dans Program.cs par le code d'example.Vous avez besoin d'ajouter vers accéssibilité, System.Drawing et System.Windows.Forms.Vous devriez changer les Types embarqué d'Interop pour l'accéssibilité à False pour éliminer les warnings de compilation.Vous pouvez changé le type de sortie du projet depuis l'Application Console vers Application Windows de tel manière à ne pas afficher une fêntre lors de l'éxécution de l'application.
Le support de validation de propriétés personalisés en implémentant un Fournisseur de propriété.
Une fois que vous avez implémenté le support basic pour un enregistrement et lecture et la validation de propriété, vous pouvez rendre vos propriétés de contrôles personalisées disponible au tests codés de l'interface utilisateur en implémentant le plug-in suivant UITestPropertyProvider.Par exemple, la procédure suivante créer un fournisseur de propriété qui permet aux tests codées de l'interface utilisateur d'accéder à la propriété des contrôles enfant d'état du contrôle de chart CurveLegend.
Pour supporter une propriété de validation personalisée
Surchargez la propriété de l'objet accéssible de la courbe légendaire Description pour la passez les valeurs de propriétés riche dans le string de description, séparé de la description du main par des point virules (et chaque autre que vous implementez si vous implementez de multiple propriétés)
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(); } } }
Créez un package d'extension de test interface utilisateur pour votre contrôle en créeant un projet de librarie de classe et ajouter des references à Accessibilité, Microsoft.VisualStudio.TestTools.UITesting, Microsoft.VisualStudio.TestTools.UITest.Common, et Microsoft.VisualStudio.TestTools.Extension.Changez le Type embarqué d'Interop pour l'Accessibilité à Faux.
Ajoutez une classe de fournisseur de propriétés qui dérive de 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 { } }
Implementez le fournisseur de propriété en plaçant les noms des propriétés et leur descripteurs dans une 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(); }
Surchargez UITestPropertyProvider.GetControlSupportLevel pour indiquez que votre assembly fournit un support spécifique pour contrôle pour votre contrôle et ses enfants.
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; }
Substituez les méthodes abstraites restantes de 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(); }
Ajoutez un package d'extension qui dérive de 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 { } }
Definissez l'atrribut UITestExtensionPackage pour l'assembly.
[assembly: Microsoft.VisualStudio.TestTools.UITest.Extension.UITestExtensionPackage( "ChartControlExtensionPackage", typeof(ChartControlExtensionPackage.ChartControlExtensionPackage))] namespace ChartControlExtensionPackage { …
Dans la classe des packages d'extension, subsituez UITestExtensionPackage.GetService pour retournez la classe fournisseur de propriétés quand un fournisseur de propriété est demandé.
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; }
Substituez les méthodes abstraites restantes et propriétés de 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); } }
Compilez vos binaires et copiez les dans %ProgramFiles%\Common\Microsoft Shared\VSTT\10.0\UITestExtensionPackages.
[!REMARQUE]
Ce package d'extension sera appliqué pour n'importe quel contrôle qui est de type "Text".Si vous testez plusieurs contrôles du mếme type, vous aurez besoin de les tester séparément et gérer quels packages d'extension sont déployé lorsque vous enregistrez vos tests.
Le support de génération de code en implémentant une class pour accéder au propriétés personalisées.
Lorsque le constructeur de tests codées d'interface utilisateur génére du code depuis un enregistrement de session, il utilise la classe UITestControl pour accédez à vos contrôles.
UITestControl uIAText = this.UIItemWindow.UIChartControlWindow.UIAText;
Assert.AreEqual(this.AssertMethod3ExpectedValues.UIATextState, uIAText.GetProperty("State").ToString());
Si vous avez implementé un fournisseur de propriétés pour fournir l'accès aux propriétés personalisées de votre contrôle, vous devez ajouter une classe spécialisé qui est utilisé pour accéder à ces propriétés pour que la génération de code soit simplifié.
ControlLegend uIAText = this.UIItemWindow.UIChartControlWindow.UIAText;
Assert.AreEqual(this.AssertMethod3ExpectedValues.UIATextState, uIAText.State);
Pour ajouter une classe spécialisé pour accéder à vos contrôles.
Implementez une classe qui dérive de WinControl et ajoutez le type de contrôle à la collection de propriétés de recherche dans le contructeur.
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"); } }
Implémentez vos propriétés personalisées de controle comme propriétés de la classe.
public virtual string State { get { return (string)GetProperty("State"); } }
Surchargez la méthonde UITestPropertyProvider.GetSpecializedClass de votre fournisseur de propriété pour retourner le type de la nouvelle classe pour la courbe légendaire de vos contrôles enfants.
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; }
Surchargez la méthode GetPropertyNamesClassType de votre fournisseur de propriété pour retourner le type de la méthode nouvelle classe PropertyNames.
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; }
Le support des actions d'Intent-Aware avec l'implementation d'un filtre d'action.
Quand Visual Studio enregistrant un test, il capture chaque événement de souris et clavier.Néanmoins, dans certains cas, l'intention de l'action peut être perdu dans la série d'événements clavier et souris.Par exemple, si votre contrôle supporte l'autocomplétion, le même jeu d'événements de clavier et sours peut résulter dans une valeur différente quand le test est rejoué dans un environnement différent.Vous pouvez ajouter un plugin de filtre d'action qui remplace la série d'événements clavier et souris avec une seule et unique action.De cette manière vous pouvez remplacé la séries d'événements de clavier et souris, résultant dans la séléction d'une valeur avec une seule action qui régle la valeur.En faisant ça, cela protège les tests codées de l'interface utilisateur des differences dans l'autocomplétion d'un environnement à un autre.
Pour supporter des actions intent-aware
Implementez une classe de filtre d'action qui dérive de UITestActionFilter, surchargeant les propriétés ApplyTimeout, Category, Enabled, FilterType, Group et Name.
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"; } }
Override ProcessRule.Cet example ici remplace une action double-clique avec un seul click d'action.
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; }
Ajoutez le filtre d'action dans la méthode GetService de votre package d'extension.
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; }
Compilez vos binaires et copiez les dans %ProgramFiles%\Common Files\Microsoft Shared\VSTT\10.0\UITestExtensionPackages.
[!REMARQUE]
Le filtre de l'action ne dépends pas de l'implementation d'accessibilité ou du fournisseur de propriétés.
Deboguez votre fournisseur de propriétés ou du filtre d'action.
Votre fournisseur de propriété et filtre d'action son implementé dans un package d'extension qui est chargé et exécuté par le constructeur de tests codés de l'interface utilisateur dans un processus séparé de votre application.
Deboguez votre fournisseur de propriétés ou du filtre d'action.
Compilez la version de déboguage de votre package d'extension copiez les fichiers .dll et .pdb vers %ProgramFiles%\Common Files\Microsoft Shared\VSTT\10.0\UITestExtensionPackages.
Exécutez votre application (pas dans le debogueur).
Exécutez le constructeur de tests codés de l'interface utilisateur.
codedUITestBuilder.exe /standalone
Attachez les débogeur au processus codedUITestBuild.
Mettez des points d'arrêt dans votre code.
Dans le constructeur de tests codés de l'interface utilisateur, créer un assignation pour éxercer votre fournisseur de propriétés, et enregistré vos actions pour éxercé vos filtres d'actions.
Ressources externes
Aide
Voir aussi
Référence
Concepts
Vérification du code à l'aide de tests codés de l'interface utilisateur