——编码的UI测试系列之四:通过编写测试代码的方式建立UI测试(上)
RealZhao,2011年3月02日
回顾
在之前的入门篇系列中,分别介绍了一个简单的示例,操作动作的录制原理,通过修改UIMap.UItest文件控制操作动作代码的生成,对象的识别原理。接下来正式进入我们UI测试的进阶篇,在这一章,将讲述如何初步通过自己编写代码的方式来建立UI测试。
示例程序
一个系统的基本功能是增,删,改,查,其中增和改界面基本一样,删就几乎是一个按钮的事,所以我做了一个程序示例(下载点我),拥有增和查两个功能,之后的操作都将会在这个示例之上进行:
系统主窗口:
该系统拥有两个功能,“添加用户”和“查询用户”,点击添加用户后,进入添加用户子窗体:
这里添加用户的时候根据情况会出现以下几个提示框:
“用户名不能为空”
“已有重名用户”
“备注不能为空”
“添加成功!”
如果在之前的主窗口,点击查询用户,则进入查询用户子窗体
注:系统默认自带了5个用户TestUser1, TestUser2, TestUser3, TestUser4, TestUser5
这个窗体不会弹任何提示框,默认进入窗体时,DataGridView里面没有加载数据,现在进行一个说明:
查询条件-用户名:表示是否按用户名查询(非模糊查询),如果不输入,默认为不按其查询
查询条件-用户类型:有三个选项“所有”,“管理员”,“一般用户”
查询条件-日期:表示是否按日期查询,如果勾上了日期CheckBox,则旁边的DateTimePicker会启用,然后选择一个具体的日期
按钮-查询:就会按以上条件查询
按钮-重置:用户名清空,用户类型变成所有,日期取消勾选
文本框-用户备注:当查询出数据以后,每选择DataGridView里面中的一行数据,用户备注TextBox会自动加载当前行的用户备注
因为篇幅的关系,这里仍然分为上下两部分,上部分介绍添加用户窗体,下部分介绍查询用户窗体和测试之间的衔接
如何设计测试
首先从前面的分析中,就可以得出添加用户实际上是检测是否有那些反例的弹出框弹出,然后正确添加用户,这里设计了一些检查点
步骤序号 | 操作步骤 | 检查点 |
1 | 运行主程序exe | 检测系统主窗口是否弹出 |
2 | 点击添加用户 | 检测添加用户子窗口是否弹出 |
3 | 输入用户名为空,用户类型选择“一般用户”,备注为空 | 检测是否弹出“用户名不能为空” |
4 | 输入用户名为“TestUser1”(系统默认就已有该用户),用户类型选择“一般用户”,备注为空 | 检测是否弹出“已有重名用户” |
5 | 输入用户名为“TestUser6”,用户类型选择“一般用户”,备注为空 | 检测是否弹出“备注不能为空” |
6 | 输入用户名为“TestUser6”,用户类型选择“一般用户”,备注为“Test” | 检测是否弹出“添加成功!” |
7 | 点击取消按钮,并退出主窗体 | 检测是否退出添加用户子窗体和主窗体 |
接下来要做的工作就很轻松,我们要将以上的检查点转换为代码
对测试进行编码
实际上,很多自动化测试项目在编写的时候都是采用边录制边编写的方法来进行的,比如复杂的操作可以先录制下来,然后手工去改某些步骤,这里我们将采用这种方法
我们需要新建一个项目,然后在添加一个编码的UI测试映射,命名为AddUserUIMap.uitest,建立之后,录制生成器会自动弹出,这个时候,我们什么也不做,直接点击“生成代码”,这样VS2010就会自动生成AddUserUIMap.cs文件和AddUserUIMap.Designer.cs文件,在第二章(下)已经提到,自定义代码可以编写到.cs文件下,因为这里不会被覆盖
实现步骤1
为了实现第一步检查点,首先我们需要捕获主窗体对象,首先我们需要打开示例程序,然后点击录制生成器的准星
从点击准星的那一刻起,按住鼠标不放,将鼠标挪动到主窗体直到主窗体被蓝色框选中,这个时候便可以松开鼠标
之后我们可以看到对象库中识别了该对象,现在点击对象库上面的“添加”图标,就可以将这个对象正式加入对象库:
然后选择录制生成器的生成代码
之后对象识别代码就生成在了AddUserUIMap.Designer.cs
之后我们就可以进入AddUserUIMap.cs(注,这里是.cs,不是.Designer.cs),实现我们第一个步骤的代码Step1_LoginSystem()
1publicvoidStep1_LoginSystem()
2{
3//操作步骤:假设程序在D盘,这句的作用是加载程序
4ApplicationUnderTest.Launch(@"D:\TestDemo.exe");
5
6//检查点:this.UI系统主窗口Window.WaitForControlExist(6000)的作用为,最多花6秒的时间等待UI系统主窗口Window出现,如果没有出现,返回false,如果出现了,则返回true
7Assert.IsTrue(this.UI系统主窗口Window.WaitForControlExist(6000),"运行主程序exe,检测系统主窗口弹出失败");
8}
实现步骤2
第一步就完成了,接下来实现第二步Step2_ClickAddUser(),因为这里大家可能觉得录制生成的方式更方便,这里我们可以采用录制的方式先生成代码,之后再将.Designer.cs生成的代码迁移到.cs文件下
首先打开录制生成器的录制
然后在菜单中选择“添加用户”
然后停止录制,点击生成代码,生成Step2_ClickAddUser()
生成完毕,我们可以看到在.Designer.cs下生成了如下代码
1publicvoidStep2_ClickAddUser()
2{
3#regionVariable Declarations
4WinMenuItem uI添加用户MenuItem=this.UI系统主窗口Window.UIMenuStrip1MenuBar.UI用户管理MenuItem.UI添加用户MenuItem;
5#endregion
6
7//Click '用户管理' -> '添加用户' menu item
8Mouse.Click(uI添加用户MenuItem,newPoint(41,7));
9}
这里我们把这些代码从.Designer.cs剪切到.cs文件下,然后删除AddUserUIMap.uitest文件下<ExecuteActions>节点中的所有内容,因为根据操作动作的录制原理可以了解到,.Designer.cs会根据.uitest文件生成代码,所以需要清空这个节点
当然这里仅仅是操作步骤实现了,但我们还要验证“添加用户”窗口是否弹出,采用和第一步相同的方式,将添加用户这个窗口添加到对象库,然后生成识别代码
之后就可以将Step2_ClickAddUser()的检查点也实现了,具体代码如下
1publicvoidStep2_ClickAddUser()
2{
3//操作步骤:在菜单中选择添加用户
4WinMenuItem uI添加用户MenuItem=this.UI系统主窗口Window.UIMenuStrip1MenuBar.UI用户管理MenuItem.UI添加用户MenuItem;
5Mouse.Click(uI添加用户MenuItem,newPoint(1,1));
6
7//检查点:检查添加用户子窗口是否弹出
8Assert.IsTrue(this.UI添加用户Window.WaitForControlExist(6000),"点击添加用户,检测添加用户子窗口弹出失败");
9}
实现步骤3-6
接下来,就是第3步到第6步的检测,3到6步基本上就只有以下几个动作,
a.输入用户名
b.选择用户类别
c.填入备注
d.点击添加按钮
e.弹出提示框,验证文本,点击OK
除了e步骤的“验证文本”操作的弹出框不是一个对象,其他的操作的对象都是一样的(OK这个button虽然属于不同的弹出框,但VS2010默认识别时会把它当成同一个,神奇吧),所以这部分操作代码是可以重用的,所以我们先打开录制生成器,然后录制以上的操作,并生成代码,和之前一样,这些代码都会从.designer.cs文件下剪切到.cs文件。(如何解决e步骤的“验证文本”操作的弹出框不是一个对象的问题,这个一会儿会介绍)
1publicvoidRecordedMethod2()
2{
3#regionVariable Declarations
4WinEdit uITbx_UserNameEdit=this.UI添加用户Window.UITbx_UserNameWindow.UITbx_UserNameEdit;
5WinComboBox uI用户类别ComboBox=this.UI添加用户Window.UICbx_UserTypeWindow.UI用户类别ComboBox;
6WinEdit uITbx_MemoEdit=this.UI添加用户Window.UITbx_MemoWindow.UITbx_MemoEdit;
7WinButton uI添加Button=this.UI添加用户Window.UI添加Window.UI添加Button;
8WinButton uIOKButton=this.UIOKWindow.UIOKButton;
9#endregion
10
11//Type 'comeon' in 'Tbx_UserName' text box
12uITbx_UserNameEdit.Text=this.RecordedMethod2Params.UITbx_UserNameEditText;
13
14//Select '一般用户' in '用户类别:' combo box
15uI用户类别ComboBox.SelectedItem=this.RecordedMethod2Params.UI用户类别ComboBoxSelectedItem;
16
17//Type 'comeon' in 'Tbx_Memo' text box
18uITbx_MemoEdit.Text=this.RecordedMethod2Params.UITbx_MemoEditText;
19
20//Click '添加' button
21Mouse.Click(uI添加Button,newPoint(52,17));
22
23//Click 'OK' button
24Mouse.Click(uIOKButton,newPoint(24,7));
25}
接下来就该解决e步骤的“验证文本”操作的弹出框不是一个对象的问题了
在第一章:一个简单的示例中,里面的弹出框是很难重用的,例如文本为“密码错误”和文本为“登陆成功”的弹出框,VS2010识别时会默认当他是两个对象,因此在对象库里面也是两个对象,但实际上,为了避免对象库对象过多,完全可以把它当成一个对象,只是说文本不一样,根据对象的识别原理,我们可以更改他的关键标识属性,让VS2010把所有的文本不同的弹出框都当成一个对象识别,然后在测试时把它的文本属性用来比对就OK了
现在我们故意让“用户名不能为空”的弹出框弹出,然后捕获上面的
然后可以看到对象库添加了这两个对象
然后我们将其保存,并生成代码,之后关闭录制生成器(一定要关闭),进入.uitest文件,寻找到对应的识别代码
1<TopLevelWindowControlType="Window"Id="UI用户名不能为空Window"FriendlyName="用户名不能为空"SpecialControlType="None"SessionId="920202">
2<TechnologyName>MSAA</TechnologyName>
3<WindowTitles>
4<WindowTitle>用户名不能为空</WindowTitle>
5</WindowTitles>
6<SearchConfigurations>
7<SearchConfiguration>VisibleOnly</SearchConfiguration>
8</SearchConfigurations>
9<AndConditionId="SearchCondition">
10<PropertyConditionName="Name">用户名不能为空</PropertyCondition>
11<PropertyConditionName="ClassName">Static