这部分主要介绍如何基于当前框架创建一个全新的自动化项目,我们约定项目路径在F盘下,项目名称为AutoProject。
在路径:“F:\自动化测试管理\框架使用说明\项目初始化模板”下双击“双击生成新项目.vbs”文件,输入【AutoProject自动化测试】点确定。
执行初始化后,可以在路径:“F:\自动化测试管理\自动化测试项目”查看到新增的项目。
目前报告服务器的地址为10.35.60.1。账号:hyholine 密码:Aa123456。在数据表【list_project】中添加一条项目的信息。
注:如果在此处添加记录,则执行报告结果插入到数据库时会失败。
在充分阅读需要和测试用例的基础上,安装TD中用例组织的结构,在目录【F:\自动化测试管理\自动化测试项目\AutoProject自动化测试\AutoProject】下创建测试集和测试用例。
1) 在QTP工具打开菜单项Tools-Options,找到Folder项:在此处添加存在函数库或对象库的文件夹路径。目的是其他配置的文件路径可以使用相对路径,相对路径会在此处配置的绝对路径下搜索匹配的文件。
2) 在QTP工具打开菜单项File-Settings,找到Resources项:在此处添加公共函数文件,默认存放在目录【公共函数库】下,如(F:\自动化测试管理\自动化测试项目\AutoProject自动化测试\公共函数库)。注:全局函数文件GlobalFunction.vbs存放在目录【Global】下,如(F:\自动化测试管理\自动化测试项目\Global)。
1) 在QTP工具打开菜单项Resources-Associate Repositories,在面板上添加公共对象库文件,并把相应的Action脚本从左侧列表添加到右侧列表中。默认存放在目录【共享对象库】下,如(F:\自动化测试管理\自动化测试项目\AutoProject自动化测试\共享对象库)。
根据需求文档和测试用例的要求设计脚本。原则上,在编写脚本之前务必详细阅读需求,在了解需求的基础上,再分析测试用例的设计结构,充分考虑测试的设计结构是否满足脚本的可实现条件。正常情况下,在分析完需求和用例后,脚本的设计雏形在脑海中应该就完成了。
1) 需求的描述和用例是否一致,是否有遗漏,矛盾,冲突等情况。
2) 脚本的设计是否可以使用用例设计的结构(一般是可以的),如果不行,就要自己设计用例的脚本实现模式。
3) 正常一个功能点会有多个用例来覆盖,因此需要考虑多个用例是否可以整合成为一个脚本来覆盖。
4) 脚本的结构要优先考虑通过数据驱动模式,当然,脚本设计的原则是以最少的成本完成最大的用例覆盖。这里的成本包括当前的设计、编写、调试脚本的时间,也包括后期需要维护的时间。基于这个原则,如果数据驱动模式不容易实现,则采用逐个对应来覆盖。
5) 在阅读需求和用例过程中,要充分考虑每一个步骤和检查点在脚本实现上是否可行。因为如果某些步骤无法实现,则应该及时做出判断,不行就放弃实现。如果待到脚本编写了一半,才发现关键的功能点无法实现,那么就等着自我反省吧。另外,为了防止上述的问题,对于比较复杂的用例,最好是自己手工执行一遍,磨刀不误砍柴工!
1) 脚本设计要考虑结构的合理性,例如:重复的业务逻辑,采用循环语句来遍历覆盖;对于可复用的业务动作或检查点要封装成函数;
2) 函数封装的原则,先查找现有函数库,存在已实现的用已实现,没有就考虑是否有可以扩展的函数,如果也没有就自己新建一个函数。
3) 新建函数的原则,不要仅仅考虑目前需求,也要考虑可扩展性。多多考虑你设计的这个函数在将来可能会用到的地方,涉及其他功能的调用,在不同场景下的调用。
4) 执行测试用例强调思维的发散,即在按照用例设计执行的基础上,发挥自己的想象力,结合需求上功能点进行交叉测试。那么在设计脚本上,也是可以借鉴,在保证基础功能点检查覆盖外,也可以加入自己认为有必要检查点。另外,对于用例中非重要检查点,脚本实现困难时可以选择不覆盖,但是,需要在对于的用例上加以说明。
5) 检查自己编写的脚本排版是否美观。
6) 对于复杂的步骤需要加以注释说明。
7) 创建函数的命名是否符合规则,是否达到见其名知其义。
1) 常数命名规则
全部字母大写,多个单词用下划线 (_) 分隔。
例如: USER_LIST_MAX 、NEW_LINE
2) 变量命名规则
驼峰命名法。
例如:UserName、Passwd
3) 形参命名规则
全部字母小写,多个单词用下划线 (_) 分隔。
例如:user_name, passwd
4) 函数命名默认规则
动作函数、使用首字母小写驼峰命名法
例如:getEmailName、setNewUserEditValue
检查函数、使用check开头的驼峰命名法
例如:checkMailListBySubject、checkWriteMailMessage
5) 对象命名规则
如果是qtp对象,使用以objqtp开头的驼峰命名法
例如:objqtp_LoginPage、objqtp_WriteMail
如果是dom对象,使用以objdom开头的驼峰命名法
例如: objdom_SettingPage、objdom_PopMenu
6) 业务大模块函数命名规则
参考使用mod开头的驼峰命名法(根据业务的不同,可以采用不同的标示)
例如:mod_SendCommonMailBase、 mod_EditSettingValue_PageStyle
代码调试是每个开发人员的基本功,良好对调试习惯和排错方法可以大大提高开发的速度。在实际生产过程中,需要针对实际情况选择最有效的排错方式,因此,针对VBS的代码调试排错,个人提出如下总结:
1) 在调试时需要在Setting窗口将错误处理选择弹窗模式,另外如果有on error resume next的语句,可能包含错误语句,可以先注释掉。
2) 在QTP中,首先需要排除语法错误,可以通过保存脚本或执行语法检查(快捷键:Ctrl+F7)判断脚本VBS语法是否正确,在底部对Information窗口可以查看到相应对错误信息,双击错误信息,可以定位到错误的脚本位置。
3) 认真分析执行中报错对信息,新手往往看到报错很紧张,没有认真阅读错误提示信息就关闭窗口进行调试,这是错的。错误提示信息是分析错误对第一手资料,同时也判断出错误对位置。
4) 设置断点、单步调试、输出变量、查看变量、执行调试动作等,这些都是常规对调试方法,可以有选择的使用。在QTP中,调试的功能还是比较不错的,基本满足调试任务对需要,相关的功能可以认真阅读分析Debug菜单项和Debug Viewer视窗。
5) 调试过程中,有些函数或业务模块过于复杂,可以将通过拆分,将认为可能存在问题对代码行拷贝出来单独调试。这样处理方式更有针对性,排除外部的干扰,降低调试对复杂度。
数据驱动是自动化测试框架中的一个重要思想,其目的是要让测试业务逻辑和测试业务数据剥离开,进行分别管理,所带来的最大好处是结构更清晰,维护更便捷。目前框架的数据驱动支持Excel和Mysql数据库的驱动模式,默认是Excel模式,Mysql模式需要另行配置。
Excel驱动模式,通过函数方法【addExcelData】或【addExcelData_Action】执行数据加载,函数根据测试集名称和测试用例名称在Excel数据表【测试驱动数据表.xlsm】中搜索,判断存在相应字段信息则会加载到QTP的数据池中。
Mysql驱动模式,不建议使用,主要原因是从维护上到数据库编辑没有Excel方便。
在脚本可以通过QTP提供的方法访问数据池中的数据,也可以使用框架封装的方法来访问(框架提供如下数据池操作方法)
1) 判断datatable表中是否存在指定的表
2) existDatasheet(Byval sheetname)
3) 判断datatable指定表中是否存在指定的列
4) existDataParameter(Byval sheetname, Byval parametername)
5) 往QTP数据表中加载Excel数据主体函数,适用于默认加载Action
6) addExcelData()
7) 往QTP数据表中加载指定的Excel数据
8) addSpecifyExcelData(setname,casename)
9) 通过封装,获取数据表中的值 GetData(Row,ParamaterID,SheetID)
10) 返回特定的数据表中的某一列有效行数 getParemeterRowCount(Byval paremetername, Byval sheetname)
11) 通过封装,获取特点字段对应的数据表中的值 GetSpecialData(Byval reField,Byval reValue,Byval geField,Byval SheetID)
用例脚本的测试集名称 对应于 Excel表中的表名【测试集名称】
用例脚本的测试用例名称 对应于 Excel表中字段【★测试用例名称】
举例:假设,新建测试集的名称(测试用例的父文件夹名称)为“MyTestSet”,测试用例名称为“MyTestCase1”。那么你需要在测试驱动数据表【测试驱动数据表.xlsm】中新建一张sheet表,命名为MyTestSet。在表中添加数据表,表的格式如上图,独立一行命名测试用例名称,在名称前加上小星星图标,表示该值为用例名称,中间部分根据脚本需要添加相应的数据,在末尾独立一行填入结束标示符【◆◆◆◆】,表示当前的用例数据加载到此为止。
为什么要写函数?为什么要定义函数库?函数封装本质是体现分工协作的关系,写的人关心函数的内部实现过程,保证功能的实现正确和健壮性。而使用的人仅仅需要函数提供的接口和返回值。这好比你想有辆车,不需要了解内部构造,但是要懂得如何驾驶它。从计算机科学上,函数的封装也体现了开发语言的美,不想让自己成为搬码工的最好方法,就是学会创造、激发自己的灵感,让自己封装出的函数足够灵活强大。
函数库分两类:
一类是用来支撑自动化测试框架和辅助脚本开发,命名为【GlobalFunction.vbs】;
一类是针对项目开发的功能函数集合,仅仅为当前的项目脚本开发服务,如:
动作函数集合(XXX_ActionFunction.vbs)
检查函数集合(XXX_CheckFunction.vbs)
对象函数集合(XXX_Object.vbs)
业务函数集合(XXX_Module.vbs)
配置函数文件(XXX_Config.vbs)
目前函数库文件的管理采用头部说明的方式,即在每份函数文件的头部编写函数的目录信息,方便搜索和查阅,在函数设计上需要检查如下10点:
1) 函数的编写风格是否美观,代码相应的缩进是否排布清晰。
2) 函数是否可以在现有函数的基础上扩展,如果可以尽量在现有函数的基础上扩展实现。
3) 函数命名是否符合规则,是否见其名知其义。
4) 函数中的内部变量是否有定义。
5) 函数中是否存在冗余的代码,即存在可以通过调用现有的功能函数来实现。
6) 函数是否充分考虑到功能的扩展和不同场景的使用。
7) 函数的功能是否正确,是否经过严格的调试和检查。
8) 函数定义为Function,是否有正确的返回值,对于不同的调用场景下是否有准确的数据返回。
9) 函数执行过程中,对于特殊情况是否有处理,例如,对象不存在或取值错误的情况下。即,函数的代码是否足够健壮。
10) 函数名是否会存在重名,如果存在重名会导致调用失败。
对象库顾名思义即用来管理测试对象。自动化测试最为核心的技术即对象的识别技术,不管哪个自动化测试工具,对象识别越厉害,吸引的使用群体就越多,市场占有率也就越大。所以说,对象识别既是自动化测试的基础,也是难点。QTP中对象库采用了树状文件式的管理方法,分为本地对象和公共对象。本地对象只提供给当前依附的脚本使用,不提供给外部的脚本使用,反之,公共对象,即一个独立的库文件,脚本需要就加载它使用,与之带来的好处,即全部的脚本对象管理仅需要维护一份对象库文件。
QTP工具在管理对象库方面是成功的,对象管理的结构很清晰,也很简单,对于开发人员来讲易于管理和使用,例如:对象的关联方法、对象的定义、对象的识别处理机制。个人觉得这些都是QTP工具上的亮点。以前,网上论坛常有人在争论描述性识别对象方法和对象库识别对象方法的优劣之分,其实,在我看来,二者本无优劣之分,仅有在特定的情况下,那种方法更适用,更方便脚本的开发。此处,我总结下我的看法:
1) 描述性对象识别方法:使用简单、体现直观、易于理解、处理灵活,在小规模项目和简单的对象识别上可以考虑使用,但是前提是对象在后期不会变更,否则随之带来的是大量的维护任务。
2) 对象库识别方法,科学管理、识别机制更强大、适用于大型的自动化项目开发,多人协作模式,以及项目对象频繁变更的场景下。一般是推荐使用对象库来管理识别对象,更有利于整个项目的管理。
上述二者之关系,好比一个是摩托车(描述性方法),一个是轿车(对象库管理),都可以用来处理对象识别,因为他们都是用发动机引擎,不过发动机的引擎规格不同,决定了它们的性能不同。摩托车固然灵活轻巧,容易驾驶上手,但是安全性不足,上了高速容易出事故,抛头颅,洒热血!而轿车呢,成本高,得先考驾照吧,即掌握使用方法,然而,相比摩托车,其速度更快、安全性更高(安全气囊)、行程更远。
另外,引用上述比喻,轿车也非万能,跑高速路上很优秀,但是走山路呢?这里想说明一个问题,对于产品的web对象可识别度不高、开发人员无法给与支持配合的情况下,对象库的使用也容易出现不灵光的现象,毕竟QTP对象库提供的识别技术有限。解决办法?请挽起袖子自己造轮子吧!这也是定义对象库文件【XXX_Object.vbs】的目的之一,对于识别难的对象(包括识别不到和识别速度慢),可以采用DOM方法封装函数对象的方式处理。这个方法目前在多个项目中被使用,效果比较好,因为这样即利用了对象库的优点,也提高了对象识别的灵活度。
对于新手,往往对对象库管理比较不感冒,使用过程也常头疼,觉得写个脚本中间还隔着个对象库,不论编写或维护脚本都比较麻烦。但是随着学习的深入以及经验的积累,对于QTP对象库会更为准确的认识。
本人在这三年来积累的一些相关认识记录下来供大家参考:
1) 使用对象库,必须先掌握对象识别机制,否则一定管理不好对象库。例如测试对象中的Web控件类别、每一类对象常用到几种定位属性、对象识别的优先顺序和策略等。
2) 对象库的目录树需要合理规划,正常情况下可以按照页面的功能排布来划分,如果存在特殊的对象,如上传弹窗,页面弹窗等,也可以根据对象的类别独立出来管理。良好的对象库目录树分类有助于脚本的编写和对象库的维护。
3) 对象命名的方式也需要统一准确,避免和其他模块的对象名称相混淆。对于集合类的对象需要做出特征标示,标示该对象属于集合对象、可以通过定义属性来定义对象。其次,良好的命名风格,可以使对象在目录树中分门别类清晰排布,如果随意命名,对象显示会呈现散乱不易管理。
4) 对象添加到对象库后,需要对特征属性进行重新确认并编辑,因为QTP默认识别到的对象属性不一定是最优方案,需要根据项目的对象特点采用最为稳定的特征属性。另外,对于使用定位属性(Index、Location、CreateTime)这类的对象,一定要慎重!多考虑在不同场景下,对象的定位是否准确。
5) 对象库中的定位属性,并不是越多越好,也不是越少也好,而是应该从稳定和识别速度上来取舍。
6) 通过对象库工具添加对象不一定能定位到属性,此时,可以使用FireBug这类工具来查看对象代码,通过分析代码抓取有效的特征值。
7) 灵活运用对象定位属性值的正则匹配方法,对于某些特征值,虽然不固定,但是有一定的规律,此时可以使用正则表达式来匹配,往往会有惊喜!
脚本批量执行就是根据给定对配置,调用执行工具对多个脚本进行遍历执行,并将执行对结果保存到指定对位置以供分析。
我们对执行工具是QTP,自然是要调用QTP的对象接口,通过定义对象接口,加载执行信息,让QTP按照我们的指示执行脚本,目前,我们对执行平台为Excel,基本可以满足批量执行对要求。基本的原理是通过VBA函数调用驱动文件【Action驱动.vbs】,驱动文件再加载Excel中的脚本执行路径信息和配置信息,通过调用QTP对象实现执行批量。
添加执行脚本的方法如下图,中对应的列【二级路径】和【Action】添加路径和脚本名,然后中【执行】列选择打钩。这样就成功添加了一条执行记录。
下图为执行对配置信息,脚本执行时会使用此处对配置信息,因此中执行脚本前,务必要检查一下配置信息是否正确。
测试报告承载了整个自动化过程的心血,我们需要通过测试报告分析脚本缺陷、产品缺陷、用例覆盖率等。拥有良好的测试报告展示效果对于一个自动化框架而言尤为重要。测试报告的载体多样化、常见的如:文本、Excel、XML、HTML。
1) 执行的过程信息:执行时间、执行信息。
2) 检查点判断信息:执行时间、执行判断结果、执行信息。
3) 排错辅助信息:截图、录像、驱动数据。
4) 报告的排序、过滤、搜索等功能。
1) 日常调试日志输出:存放在项目路径【输出数据\用例测试报告日志】下。
2) 脚本执行过程日志输出:存放在项目路径【输出数据\用例测试报告日志\debug】下。
3) 批量执行Excel报告:存在在项目路径【输出数据】下的测试报告.xlsm。
4) 批量执行Web报告:存放在http://auto.35test.cn/readqtp下。