一起谈.NET技术,VS2010测试功能之旅:编码的UI测试(3)-操作对象的识别原理...
回顾
在之前的两章分别介绍了一个简单的示例, 操作动作的录制原理,通过修改UIMap.UItest文件控制操作动作代码的生成。想必大家对编码的UI测试操作动作的录制应该有一定了解了,在UI操作中,操作动作总是离不开具体的操作对象,例如点击,拖动,填写值等操作,总是要对文本框,或者按钮,窗体这些对象进行操作,不是凭空生成的。本章作为入门篇的最后一章,将会说明编码的UI测试是如何识别这些对象的,并介绍UIMap.UItest文件是如何生成对象识别代码。
对象的识别原理
之前我们录制的时候,录制生成器解析了我们的操作对象,并且为我们生成了对象识别代码(也就是UIMap.UItest下<Map>节点的那部分),以便我们在回放的时候,能够识别到我们要操作的是哪一个对象。
在编码的UI测试中,对象的识别主要是同时按以下三个方面进行。
1. 按对象类别:对象属于什么类别,例如是button还是textBox 。
2. 按关键标识属性:能唯一识别该对象的属性 。
3. 按层级关系:对象在其父对象中的层次 。
下面开始进行详细介绍:
一、按对象类别:
为便于理解,以web程序为例,假设我们的识别代码中,写明让VS2010按WebButton识别一个对象,那么VS2010则会在页面源码中只找到那些html标签是<input type=“submit”>的控件,如果识别代码中描写的是按WebLink识别对象,则VS2010只在页面源码中找到那些是<a>的标签。
二、按关键标识属性:
通过对象类别,已经能识别出来某一类的对象,在这个基础上,接下来就需要用关键识别属性进行精准标识了,我们需要找出能唯一识别该对象的属性,假如一个窗体如下。
这个窗体中包含了3个button,我们想让VS2010操作到第一个Button,如何区分这些Button呢?这就要用到关键标识属性来标识唯一一个对象。
关键标识属性分为两种----自身标识属性和辅助标识属性。
1、自身标识属性:
也就是属于对象的属性,例如,button拥有Name,Text,Enable,BackColor等属性,我们假设上面那个窗体的Button的各个属性如下。
很明显可以发现,第一个button的Name属性和和其他的button不一样,那么可以用其作为他的关键标识属性,并且写在识别代码中,这样vs2010就可以在这些button中能唯一识别他,例如,将Name=button2写到识别代码中,就可以唯一识别第二个Button。
假设3个button的Name一样,而BackColor不同,也可以用BackColor作为关键标识属性。
2、辅助标识属性:
在自动化测试中,还有一种属性叫做辅助标识属性,他并不属于对象的属性,但可以辅助标识对象。
假设刚才那个窗体的各button属性如下:
可以发现他们的自身属性都是一模一样的,那么怎么做才能让VS2010识别他呢?仔细观察可以发现这样一个情况。
我们可以通过该对象是第几个对象这样的辅助属性进行标识他。
比如如果要识别第3个Button,则需要在识别代码中设置其辅助标识属性“对象序号”为3。
三、按层级关系:
虽然上面确定了唯一对象,的确已经可以标识出对象了,不过实际上在识别的时候还会按层级关系查找,例如第一章提到的一个简单的窗体。
我们用录制生成器解析他的第一个文本框Tbx_uid,在自动生成的识别代码中,他们的层级关系是这样的。
对应到刚才的Form,层级为:
VS2010在识别这个Textbox1的时候,会只识别属于 系统登录Window下的Tbx_uidWindow下的Tbx_uid文本框。
(注:按照常规的理解,其实应该“系统登录窗体”和“Tbx_uid文本框”只有两个层级,也就是窗体下直接就是文本框,但是VS2010默认解析的时候,会把一个TextBox解析成两个层级,分为TextBoxWindow和TextBoxEdit,结果本来应该总共只有两级结果搞成了三级,如果仔细观察可以发现其他控件也是这样的,所以在这里纠结的朋友希望你们看到此段后能够减轻些疑惑...)
UIMap.UItest文件控制识别代码的生成
在第二章上部分已经提到,在UIMap.uitest文件中,对象的识别代码的生成部分是放在<Maps>节点下的,点击生成代码后,会将其真正起作用的识别代码生成到UIMap.designer.cs下,那么他们的代码究竟是怎样的呢?
以刚才那个窗体生成的代码为例,我们要识别TextBox1,如果使用录制生成器,把TextBox1填入到对象库,我们来看看他生成的识别代码(可以简略看,下面会有说明)。
<UIMap Id="UIMap1">
<TopLevelWindows>
<TopLevelWindow ControlType="Window" Id="UI 系统登录Window" FriendlyName="系统登录" SpecialControlType="None" SessionId="199642">
<TechnologyName>MSAA</TechnologyName>
<WindowTitles>
<WindowTitle> 系统登录</WindowTitle>
</WindowTitles>
<SearchConfigurations>
<SearchConfiguration>VisibleOnly</SearchConfiguration>
</SearchConfigurations>
<AndCondition Id="SearchCondition">
<PropertyCondition Name="Name"& gt;系统登录</PropertyCondition>
<PropertyCondition Name="ClassName" Operator="Contains">WindowsForms10.Window</PropertyCondition>
<PropertyCondition Name="ControlType">Window</PropertyCondition>
</AndCondition>
<SupportLevel>0</SupportLevel>
<Descendants>
<UIObject ControlType="Window" Id="UITbx_uidWindow" FriendlyName="Tbx_uid" SpecialControlType="None">
<TechnologyName>MSAA</TechnologyName>
<WindowTitles>
<WindowTitle> 系统登录</WindowTitle>
</WindowTitles>
<SearchConfigurations>
<SearchConfiguration>VisibleOnly</SearchConfiguration>
</SearchConfigurations>
<AndCondition Id="SearchCondition">
<PropertyCondition Name="ControlName">Tbx_uid</PropertyCondition>
<PropertyCondition Name="ControlType">Window</PropertyCondition>
</AndCondition>
<SupportLevel>0</SupportLevel>
<Descendants>
<UIObject ControlType="Edit" Id="UITbx_uidEdit" FriendlyName="Tbx_uid" SpecialControlType="None">
<TechnologyName>MSAA</TechnologyName>
<WindowTitles>
<WindowTitle> 系统登录</WindowTitle>
</WindowTitles>
<SearchConfigurations>
<SearchConfiguration>VisibleOnly</SearchConfiguration>
</SearchConfigurations>
<AndCondition Id="SearchCondition">
<PropertyCondition Name="Name"& gt;密码 :</PropertyCondition>
<PropertyCondition Name="ControlType">Edit</PropertyCondition>
</AndCondition>
<SupportLevel>0</SupportLevel>
<Descendants />
</UIObject>
</Descendants>
</UIObject>
</Descendants>
</TopLevelWindow>
</TopLevelWindows>
</UIMap>
</Maps>
别看UIMap.uitest里为这些对象生成的了一大堆代码,其实对象中真正管作用的属性就ControlType,ID两个:
ID这个属性表示调用对象在对象库中的ID,例如在第二章下部分,编写ExecuteActions的时候,描述对那个对象进行操作
ControlType这个属性用于描述按什么类别来识别对象,识别原理之一的对象类别就是用这个表示
而管作用的节点也就这么两个:
<AndCondition>这个节点表示识别条件,他的子节点为<PropertyCondition>,表示具体识别条件,识别原理之二的关键标识属性就用这个表示
<Descendants>这个节点用于存放这个对象的子对象,识别原理之三的层级关系就是用这个表示 。
现在把上面自动生成的代码优化一下,把不必要的代码删除,并加上注释。然后再使用这段XML代码在录制生成器生成UIMap.designer.cs代码:
<UIMap Id="UIMap1">
<TopLevelWindows>
<!-- 表示最高级别的窗体,属性ControlType表示按类型“Window”类型识别对象,对应识别原理之一-->
<TopLevelWindow ControlType="Window" Id="UI 系统登录Window">
<!--TechnologyName标签没有实际作用,但是删除了会报错,因此保留,之后的也是-->
<TechnologyName>MSAA</TechnologyName>
<AndCondition Id="SearchCondition">
<!-- 表示窗体的关键标识属性,识别的时候寻找Name属性为“系统登录”的窗体,对应识别原理之二-->
<PropertyCondition Name="Name"& gt;系统登录</PropertyCondition>
<!--表示窗体的关键标识属性,识别的时候寻找ClassName属性为“WindowsForms10.Window”的窗体-->
<PropertyCondition Name="ClassName" Operator="Contains">WindowsForms10.Window</PropertyCondition>
</AndCondition>
<!-- 表示窗体的子对象,对应识别原理之三-->
<Descendants>
<!--UI 对象,按类型“Window”类型识别-->
<UIObject ControlType="Window" Id="UITbx_uidWindow">
<TechnologyName>MSAA</TechnologyName>
<AndCondition Id="SearchCondition">
<!-- 关键标识属性,ControlName属性为“Tbx_uid”的对象-->
<PropertyCondition Name="ControlName">Tbx_uid</PropertyCondition>
</AndCondition>
<!-- 他的子对象-->
<Descendants>
<!--UI 对象,按类型“Edit”(文本框)类型识别-->
<UIObject ControlType="Edit" Id="UITbx_uidEdit">
<TechnologyName>MSAA</TechnologyName>
<AndCondition Id="SearchCondition">
<!-- 关键标识属性,Name属性为“密码 :”-->
<PropertyCondition Name="Name"& gt;密码 :</PropertyCondition>
</AndCondition>
<Descendants />
</UIObject>
</Descendants>
</UIObject>
</Descendants>
</TopLevelWindow>
</TopLevelWindows>
</UIMap>
</Maps>
接下来使用录制生成器生成UIMap.designer.cs代码,可以看到代码如下:
public class UI 系统登录Window : WinWindow//这里的继承于WinWindow,是根据刚才XML文件里的属性 ControlType="Window"生成的,表示按Window识别,对应识别原理之一
{
public UI 系统登录Window()
{
//这里是搜索条件,也就是关键识别属性,根据XML 文件的AndCondition节点中的内容生成,对应识别原理之二
#region 搜索条件
this.SearchProperties[WinWindow.PropertyNames.Name] = " 系统登录";
this.SearchProperties.Add(new PropertyExpression(WinWindow.PropertyNames.ClassName, "WindowsForms10.Window", PropertyExpressionOperator.Contains));
#endregion
}
// 这里是他的子对象,对应于XML文件的Descendants节点,对应识别原理之三
#region Properties
public UITbx_uidWindow UITbx_uidWindow
{
get
{
if ((this.mUITbx_uidWindow == null))
{
this.mUITbx_uidWindow = new UITbx_uidWindow(this);
}
return this.mUITbx_uidWindow;
}
}
#endregion
#region Fields
private UITbx_uidWindow mUITbx_uidWindow;
#endregion
}
[GeneratedCode(" 编码的 UI 测试生成器", "10.0.30319.1")]
public class UITbx_uidWindow : WinWindow// 这里的继承于WinWindow,是根据刚才XML文件里的属性ControlType="Window"生成的,表示按Window识别
{
public UITbx_uidWindow(UITestControl searchLimitContainer) :
base(searchLimitContainer)
{
// 这里是搜索条件,也就是关键识别属性,根据XML文件的AndCondition节点中的内容生成
#region 搜索条件
this.SearchProperties[WinWindow.PropertyNames.ControlName] = "Tbx_uid";
#endregion
}
// 这里是他的子对象,对应于XML文件的Descendants节点
#region Properties
public WinEdit UITbx_uidEdit// 这里的类型为WinEdit,是根据刚才XML文件里的属性ControlType生成的(ControlType="Edit")
{
get
{
if ((this.mUITbx_uidEdit == null))
{
this.mUITbx_uidEdit = new WinEdit(this);
// 这里是搜索条件,也就是关键识别属性,根据XML文件的AndCondition节点中的内容生成
#region 搜索条件
this.mUITbx_uidEdit.SearchProperties[WinEdit.PropertyNames.Name] = " 密码 :";
#endregion
}
return this.mUITbx_uidEdit;
}
}
#endregion
#region Fields
private WinEdit mUITbx_uidEdit;
#endregion
}
总结
在本章介绍了VS2010的对象识别原理,想必大家对这个应该有所了解了吧?
我曾今在用UI测试做项目的时候,经常会发现这样那样的对象不能用录制生成器识别,这个时候怎么办呢?了解了对象识别原理,就可以自己改XML文件来控制对象的识别,如果有想做这方面练习的朋友,可以留下你的邮箱,我这里正在编写一个C# Winform小程序,这个程序上的所有控件都经过特殊处理,无法用录制生成器识别,只有通过自己修改XML文件来控制它的识别,如果想试试自己的身手,别忘了留下邮箱哦~~
到这里编码的UI测试的入门篇就完结了,接下来会进入进阶篇,以实际的例子描述如何对一个项目进行测试。
附1:VS2010编码的UI测试支持识别的对象
平台 | 支持级别 |
Windows Internet Explorer 7.0 Windows Internet Explorer 8.0 (包括 HTML 和 AJAX) |
完全支持 |
Windows Internet Explorer 6.0 | 不支持 |
镶边OperaSafari | 不支持 |
Silverlight 3.0 | 不支持 |
Flash/Java | 不支持 |
Windows 窗体 2.0 及更高版本 |
完全支持 注意 完全支持 NetFx 控件,但并非支持所有第三方控件。 |
WPF 3.5 及更高版本 |
完全支持 注意 完全支持 NetFx 控件,但并非支持所有第三方控件。 |
Windows Win32 | 可适用于某些已知问题,但不正式支持 |
MFC | 可适用于某些已知问题,但不正式支持 |
SharePoint | 部分支持 |
Office 客户端应用程序 | 不支持 |
Dynamics (Ax) | 部分支持 |
SAP | 不支持 |
Citrix/终端服务 | 部分支持 |
注:Silverlight4 现在已支持,详情见http://www.silverlightshow.net/news/Coded-UI-testing-for-Silverlight-4-now-available-.aspx,
园子里scottxu已有这方面研究,相关文章http://www.cnblogs.com/scottxu/archive/2011/02/28/1967112.html
public class UI 系统登录Window : WinWindow//这里的继承于WinWindow,是根据刚才XML文件里的属性 ControlType="Window"生成的,表示按Window识别,对应识别原理之一
{
public UI 系统登录Window()
{
//这里是搜索条件,也就是关键识别属性,根据XML 文件的AndCondition节点中的内容生成,对应识别原理之二
#region 搜索条件
this.SearchProperties[WinWindow.PropertyNames.Name] = " 系统登录";
this.SearchProperties.Add(new PropertyExpression(WinWindow.PropertyNames.ClassName, "WindowsForms10.Window", PropertyExpressionOperator.Contains));
#endregion
}
// 这里是他的子对象,对应于XML文件的Descendants节点,对应识别原理之三
#region Properties
public UITbx_uidWindow UITbx_uidWindow
{
get
{
if ((this.mUITbx_uidWindow == null))
{
this.mUITbx_uidWindow = new UITbx_uidWindow(this);
}
return this.mUITbx_uidWindow;
}
}
#endregion
#region Fields
private UITbx_uidWindow mUITbx_uidWindow;
#endregion
}
[GeneratedCode(" 编码的 UI 测试生成器", "10.0.30319.1")]
public class UITbx_uidWindow : WinWindow// 这里的继承于WinWindow,是根据刚才XML文件里的属性ControlType="Window"生成的,表示按Window识别
{
public UITbx_uidWindow(UITestControl searchLimitContainer) :
base(searchLimitContainer)
{
// 这里是搜索条件,也就是关键识别属性,根据XML文件的AndCondition节点中的内容生成
#region 搜索条件
this.SearchProperties[WinWindow.PropertyNames.ControlName] = "Tbx_uid";
#endregion
}
// 这里是他的子对象,对应于XML文件的Descendants节点
#region Properties
public WinEdit UITbx_uidEdit// 这里的类型为WinEdit,是根据刚才XML文件里的属性ControlType生成的(ControlType="Edit")
{
get
{
if ((this.mUITbx_uidEdit == null))
{
this.mUITbx_uidEdit = new WinEdit(this);
// 这里是搜索条件,也就是关键识别属性,根据XML文件的AndCondition节点中的内容生成
#region 搜索条件
this.mUITbx_uidEdit.SearchProperties[WinEdit.PropertyNames.Name] = " 密码 :";
#endregion
}
return this.mUITbx_uidEdit;
}
}
#endregion
#region Fields
private WinEdit mUITbx_uidEdit;
#endregion
}
转载于:https://www.cnblogs.com/waw/archive/2011/09/02/2162940.html
一起谈.NET技术,VS2010测试功能之旅:编码的UI测试(3)-操作对象的识别原理...相关推荐
- VS2010测试功能之旅:编码的UI测试(6)- 提高UI测试稳定性的8个方法(下)
VS2010测试功能之旅 --编码的UI测试系列之六:提高UI测试稳定性的8个方法(下) RealZhao,2011年5月11日 回顾 在之前,我们介绍了提高UI测试稳定性的8个方法的前6个,接下来介 ...
- 【转】VS2010测试功能之旅:编码的UI测试(2)-操作动作的录制原理(上)
VS2010测试功能之旅 --编码的UI测试系列之二:操作动作的录制原理(上) RealZhao,2011年2月18日 回顾 在之前我们介绍了如何用VS2010的UI测试功能创建一个简单的示例,大致描 ...
- 一起谈.NET技术,VS2010测试功能之旅:编码的UI测试(2)-操作动作的录制原理(下)...
回顾 在本章上部分介绍了操作动作的录制原理,描述了操作动作是如何录制,UIMap.uitest和UIMap.Designer.cs的代码如何生成,以及他们的结构.在这个部分,将着重说明如何通过修改UI ...
- VS2010 测试功能之旅:编码的UI测试(4)-通过编写测试代码的方式“.NET研究”建立UI测试(下)...
回顾 最近比较忙,距离上次更新的时间较久,见谅. 在本章上部分,介绍了"添加用户"窗口的测试代码编写.想必大家也看到了,在UIMap.cs文件中实现自定义编码是一件很轻松的事情,接 ...
- VS2010测试功能之旅:编码的“.NET研究”UI测试(2)-操作动作的录制原理(上)...
回顾 在之前我们介绍了如何用VS2010的UI测试功能创建一个简单的示例,大致描述了如何使用编码的UI测试进行录制和回放,在这章会着重描述VS2010是如何录制操作,并且生成代码,以及初步介绍如何通 ...
- 使用编码的 UI 测试来测试 Windows 应用商店应用
自从Win8应运而生以来,Windows应用商店便立马成为开发者展示的舞台,而这短短的几年里应用的数量就可数以万计,这也不可避免地出现了良莠不齐的局面.我们都知道Visual Studio是目前最流行 ...
- 通过VS编码的UI测试来测试用户界面(一)
通过VS编码的UI测试来测试用户界面(一) 1.前期操作: 1.文件->新建->项目 2.测试->编码的UI测试项目->填写项目名称(这里就不改变了) 3.点击确定后会出现如下 ...
- 测试功能范围_IT8511+电子负载 OCP?测试功能
IT8511+电子负载 OCP 测试功能 IT8500+系列电子负载具有过电流保护(OCP)测试功能,在 OCP 测试模式下,当输入电压达到 Von 值时,延时一段时间,电流开始工作,每隔一定时间按步 ...
- 前端如何实现网络速度测试功能_前端组件单元测试
啥?单元测试?我哪有时间写单元测试? 从软件质量说起 日常生活中,商品质量永远是我们进行选择时需要着重考虑的因素,计算机软件也不例外.优秀的软件应当如我们预期的一样工作,能够正确地处理所有功能性需求. ...
最新文章
- 在 Linux 下运行 ASP.NET 2.0
- 常用加密算法的Java实现(一) ——单向加密算法MD5和SHA
- 参数--argumengs
- Rest之一-什么是REST?以及RESTful的实现
- C语言入门经典题目及其答案
- 配置postfix+dovecot+mysql+postfixadmin+squirrelmail 邮件系统笔记
- Android实用代码七段(二)
- VS2010链接SQLsever2008数据库时出现[DBNETLIB][ConnectionOpen (Connect()).]SQL Server 不存在或拒
- Vue之不常注意的点
- pdf reference官方指南之-图片
- 带外壳版本4G LTE模块,包括华为ME909系列、移远EC20系列、移远EC200T系列
- JAVA垃圾回收器与垃圾回收算法
- ROS中关于yaml文件参数的读取,和nh.param函数
- XP系统最大能支持多少内存
- WIFI能杀死植物吗?
- 作业调度系统--SGE和PBS的使用方法
- JAVA-读取excel转成html 将excel表格转换为HTML文件格式 转成前端表格样式
- FileDetector-基于java开发的照片整理工具
- 小米一面、二面,面经
- kali系统升级(包含软件信息、所有软件、整个系统)
热门文章
- android easylink 搜索设备_手把手教你将数据从Android移动到iPhone步骤与技巧
- c++ array容器 传参_华东理工:氮和氧共掺杂的分级多孔碳,用于超级电容器的电极材料...
- java jersey使用总结_jersey使用指南
- 哪个版本好_《道德经》道尽人生大智慧,哪个版本《道德经》的注释比较好呢?...
- 远程服务器如何传文件大小,linux服务器远程传文件大小
- Go实现启动参数加载
- 在 Linux 中把一个网页转换成 PDF的技巧介绍
- Cargo 教程介绍
- 介绍java -cp java -jar的区别
- 十分钟理解Java泛型擦除