发布新日志

  • QTP识别和操作对象的原理

    2007-06-22 08:44:00

        QTP为用户提供了两种操作对象的接口,一种就是对象的封装接口,另一种是对象的自身接口。
        对象的自身接口是对象控件本身的接口,只要做过软件开发,使用过控件的人应该很清楚。
        对象的封装接口是QTP为对象封装的另一层接口,它是QTP通过调用对象的自身接口来实现的。


    两种接口的脚本书写格式的差别在于:
        自身接口需要在对象名后面加object再加属性名或方法名,封装接口就不用在对象名后面加object。

        比如操作JavaEdit对象,通过QTP封装的封装接口,脚本如下:
        设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").Set "NE1"
        读取JavaEdit的内容:
         msgbox JavaDialog("Add NE").JavaEdit("NE Name").GetROProperty("value")

        如果通过JavaEdit的自身接口,脚本如下:
        设置JavaEdit的内容:
        JavaDialog("Add NE").JavaEdit("NE Name").object.setText("NE1")
        读取JavaEdit的内容:
        Msgbox JavaDialog("Add NE").JavaEdit("NE Name").object.getText()

        QTP执行JavaEdit().Set语句时,是通过执行JavaEdit().object.setText()来实现的。
        QTP执行JavaEdit().GetROProperty("value"),是通过执行JavaEdit().object.getText()来实现的。
        JavaEdit对象的封装接口Set()和GetROProperty("value"),是QTP封装JavaEdit对象的自身接口setText()和getText()而得来的。

        对象的封装接口是QTP使用的缺省接口,我们录制出来的脚本都是使用封装接口,大家用的也都是封装接口。
        但是封装接口不如自身接口丰富,因为QTP只是封装了部分常用的自身接口嘛。
        所以我们在需要时,可以绕过封装接口,直接调用对象的自身接口。
        不过有些自身接口不够稳定,在实践中偶尔会出现问题,但是概率很少。
       封装接口有相应功能的话,就尽量用封装接口吧!

      
        理解了封装接口和自身接口的原理,我们就可以更加灵活的操作对象了。

        但是我们怎么知道对象都有哪些封装接口和自身接口呢?
        其实很简单,用对象查看器(Object Spy)查看对象,在查看窗口里有列出这些接口,包括属性和方法。
        窗口中间有选择栏让你选择Run-time Object或者Test Object,当你选择Run-time Object时,它显示的就是对象的自身接口(自身的属性和方法)当你选择Test Object时,它显示的就是对象的封装接口(封装的属性和方法)

        明白了这些,你还等什么呢?快拿起对象查看器,看看对象都有哪些封装接口和自身接口,肆意的操作它,玩弄它吧!

        比如执行
        JavaDialog("Add NE").JavaEdit("NE Name").object.setVisible(false)
         哈哈,你的JavaEdit对象就当场消失不见了!!!

  • (Quote)加强测试用例在测试过程中的地位

    2007-06-15 12:01:22

    常闻测试人员如此抱怨:

    测试用例在实际中没有起多大作用;

    在实际测试时根本没有按用例执行;

    测试执行后没有把新的用例补充到用例库中……

    先说说当前我们的软件企业为何测试流程不规范:

    1)从事物的发展规律看,软件测试行业在我国还是新兴行业,目前还处于起步和探索期,虽然国外的同行业发展到了一定阶段,但事实上他们也在不断否定自我并摸索着更直接有效的方法;而国内的测试行业发展期不足10年,所谓的测试管理流程不规范,也就情有可原了。

    2)从企业个体角度讲,测试部门的整顿和加强,按照企业自身发展的优先层次,还没有被纳入优先解决的程度,开拓市场/签售定单才是首要问题,也是维系企业生存发展的命脉。当然国内很多优秀的大中型软件公司的测试部门相对完善,如神州数码/用友/金蝶等,他们和大型跨国软件公司的合作,也从中汲取了宝贵的管理经验。

    3)还有一个普遍存在的问题。近几年国内软件企业为了加强企业的竞争优势和名气提升,通常大搞特搞ISO/CMM认证;笔者并不反对这么做,但通过这些认证后的企业有多少真正按照那些规定/设计的标准在后续的测试或软件开发管理工作中着手开展下去呢?社会上流传着这样的话:任何认证到中国,最后都免不了砸牌了!笔者读书时很多高校搞的MCSE认证,有培训机构明目张胆声称“百分百通过率”!当年也有专门媒体报道此事。听到这样的话,我们都会寒心,这里真心希望我们的软件企业通过ISO/CMM后真正为企业的内部软件开发流程带来一点曙光。

    4)最后一个原因,我想是企业内部测试管理人员和技术人员技能的不足,还有自身工作态度的不够端正。有了再好的规范标准,没人遵守不行!没人实施不行!应该说,很多中小软件企业的高层都或多或少的逐渐意识到软件测试的重要性和必要性,以及它的标准化/流程化改革的紧迫性,但也有很多的工程师/技术人员并不理会这套,常常在实际工作中投机取巧;也有很多测试管理人员经验不足/技能不够,对公司测试管理工作考虑不到位,和开发工程师交流不充分,和上层领导反映不及时等等。

    总之,任何问题的出现都不是单方面的原因,从宏观的社会形势到微观的企业个人,都有无可推卸的因素;正因为如此,解决问题也要对症下药,如何完善软件测试流程,就要从小处出发;本文不可能将软件测试流程改进的话题阐述的面面俱到,因此只谈测试用例的管理流程改进。

    测试用例在实际中没有起多大作用,在实际测试时根本没有按用例执行,测试执行后没有把新的用例补充到用例库中…为何如此?我们分析认为,根本原因是测试流程不完善,针对测试用例的管理流程更不完善,从三个方面具体来说:

    • 测试用例是软件测试工作执行环节的依据,如果这个依据都没用了,那是不是说这个依据不明确,依据设计的不合理呢?答案是肯定的!
    • 制定了完备有效的测试用例,为什么不按测试用例执行测试呢?首先是因为企业没有严格和良好的机制促使测试执行者这样做,其实是个别测试人员投机取巧心理的表现。
    • 测试用例设计得不可能天衣无缝,测试执行过程里肯定会发现有些测试路径或数据在用例里没有体现;那么事后该将其补充到用例库里,以方便他人和后续版本的测试;如果没有这样做,那么测试部门负责人和每个测试员都难辞其疚,是该重新坐下来思考一下公司的测试用例管理规范或流程了。

    那么究竟如何做,才能尽量避免上述问题呢?我们不妨从需求阶段就把这些问题考虑进去,以便从初始就力争将问题缩到最小,以防后期出现问题是互相推卸责任或干脆束手无策!

    ――软件需求分析阶段,我从来认为测试人员从软件生命周期的需求阶段就开始介入,因为测试人员的工作通常开展在该周期的末尾,如果前期不涉入,如何通晓整个系统的架构而对其测试呢?虽然该观点被大多数同行所认可,但我知道依然有很多公司为了节省费用,不让测试人员参与前期调研或制定需求,经常的做法是等到系统开发完毕或将近完成,跟测试经理说一声“这边有个项目,你找几个人来测一下吧!”经验表明,这样的做法实不可取。

    测试人员在需求阶段的任务有:

    • 全面了解系统需求,从客户角度考虑软件测试需要达到的验证值。
    • 参与软件需求调研,以测试角度分析需求的可测性;对不可测问题与客户或项目经理协调解决。

    如果企业采用类似与rational requistepro的需求管理工具,这个工作也需要测试人员的配合实施。

    ――软件分析设计阶段,测试人员除制定测试计划书等本职工作外,我认为还有一个必不可少的任务,那就是将系统的可测性落实到书面文档,以备将来编写测试用例。

    之所以要这么做,是因为考虑到很多企业编写测试用例直接参考需求规格说明书或者分析流程图,这样跨度大,难度也大,是造成测试用例不完备、覆盖范围小的重要原因。

    如果公司采用类似于rational rose的建模分析工具,这个工作更好执行;如果没有,那么测试人员更有必要编写一份《软件功能点测试描述书》,它是软件的详细测试分析文档,其主旨是将系统分析人员的分析文档加工成站在测试角度的功能点分析文档,重要的是描述对系统分解后每个功能点逐一的校验描述,包括何种方法测试 何种数据测试 期望测试结果等,这些信息都是描述性的,无须具体数据;它的作用是据此编写测试用例,以及测试执行时的参考依据,它直接来源于需求,覆盖最全,也最贴近客户。

    当然该文档不是非要不可,我只是提倡一种原则,如果有类似的替代文档或有自动工具可实现此功能,则会倍加受推崇!

    ――软件开发阶段,编写测试用例。我不想从技术角度探讨到底如何编写功能强大质量优异的测试用例(可参见我在“天若有情”转载的这篇文章- 如何设计编写软件测试用例),这里只想从管理角度和大家谈谈如何有效控制测试用例的流程。应该遵守的原则是:

    首先,从覆盖率来说,测试用例库的用例要达到最大覆盖软件系统的功能点。按照我上述所言的测试工程师从前期阶段顺次下来,编写测试用例时,基本就是将《软件功能点测试描述书》中的每个功能点进行操作上的细化:一是将从步骤上描述到达校验点的方式,二是从内容上以何种数据校验功能点。

    其次,从数量来讲,我觉得很多公司的测试用例太少,甚至远远不能覆盖系统需求,这也是很多测试人员测试开展前期按照用例执行,渐渐凭“意念”去测试的原因。应该说测试用例的数量很难用数学模型来模拟,更没办法衡量,但凭借个人经验来说,一个多于半年开发周期(指从编码开始直到提交客户的时间段)的软件系统,它的用例数量不要低于4000个,甚至更多!也许有人惊讶这一数字,不过了解IBM Microsoft 的人士会认为4000还是很少的。试想,对于一个中型软件系统,如果设计出5000个用例,那它的测试覆盖率还怕不高么!

    再次,如此众多的测试用例的管理。是的,需要管理工具软件!本人从来都反对以word或excel来编写测试用例,那样不仅在格式上难于编写——尤其对于一些共性内容:测试目标、测试环境、参考说明等,每次都要拷贝;而且难于管理——几千个文档文件放在一个共享文件夹,你的眼睛要必将经过缭乱的洗礼!更是难于执行——莫非真要针对几千个用例都是打开一个word、执行测试、输入测试结果、关闭word?而且,根本没办法追踪测试结果——输入完本轮回归测试的结果,下一论输入哪里?输入了这些测试结果什么用?用它追踪什么?追踪得到吗?

    使用word等软件编写测试用例的种种不便不多说,但换个思路思考一下使用集成工具的种种优势就一见分晓。测试同业者们都了解的测试用例管理工具便是rational testmanager(点击http://www-900.ibm.com/cn/software/rational/products/testmanager/index.shtml了解其基本功能),其实还有很多国内外中小型工具,如微创的testcase manager(点击http://www.wicresoft.com/products/devmgmt/tcm/docs/whitepaper.pdf下载工具白皮书)等,他们是专业的测试用例管理工具,其设计出发点就已经考虑到了我们上述的种种困境,因此给予了良好的解决方案。

    而且,个人觉得测试行业的快速发展,必将带来从每个环节都逐渐向自动化和标准化方向迈进,尽早适应这一趋势,不仅提高了工作效率,也提高了企业的信誉和名誉。

    最后,说一下测试用例格式上一般说明外的几个要点:

    一是在测试管理工具中制定适合本公司的测试用例模版

    二是模版有关键字索引,以方便按关键字分类查找,如测试方法(分手工/自动两种)

    三是测试用例要有状态跟踪,如执行失败要链接到缺陷报告

    四是测试用例的修改及运行都有日志记录

    ――软件测试阶段,测试负责人划分不同的测试阶段(如集成测试 系统测试 回归测试 性能测试等),再划分不同的子测试周期(如前两个星期做冒烟测试,可手工,也可自动;接着做第一模块功能测试,顺次…),再为项目测试人员分配测试用例,测试人员则按照详细的用例文档去执行测试,这里要遵循的几个原则是:

    A有健全且严格的体制保证测试执行者严格按照测试用例执行测试。这并不妨碍测试者创造力的发挥,因为前期用例设计和编写就是项目全体测试人员智慧的结晶!我们一直追问众多测试工程师加班加点辛苦工作的原因,其实大都发生这一阶段,如此实施,即便没有解决根本问题,也会大大提高测试执行效率。

    B如有对用例认识模糊或遗漏的地方,必须经测试负责人或项目其他管理人员同意方可更新用例库。

    C测试负责人每日负责跟踪本测试子周期或阶段的测试用例执行情况,以及每日提交的缺陷报告,根据执行进展状态以及缺陷数量或严重等级和项目高层或其他人员交流,商议解决途径,并确定或调整未来时间的测试任务。

    D测试执行者负责执行自己区域的测试用例,也要负责跟踪该区域软件缺陷的修改进展,根据其状态不断验证软件功能点。

    E应该提及的是,大多数软件公司都采用集成的缺陷管理工具来管理软件缺陷,如rational clearquest、mantis、bugzilla、TestTrack Pro等,这是好事情,因为这些集成工具都提供了清晰的报告模版及优秀的追踪功能,测试团队的每一成员按照自己的角色和权限要不断追踪缺陷的状态。

    F对于自动测试(包括性能/压力测试),有一些特殊要点。本人的原则是自动化测试无须编写测试用例,故而到此阶段才提及自动化测试;只要在编写时将用例库里适合或需要自动测试的用例的测试方法(不同工具可能名称不同)设为自动即可。自动化测试的实施方案有所不同,每款测试工具的使用和流程也不同,但都是从在这一阶段编写测试脚本,并运行自动测试。针对自动化测试原则,可参阅我的 自动化测试要点,这里要提的几个基本原则是:

    一是选择恰当的测试工具品牌,并要求提供培训

    二是项目测试成员有专人负责此事的进行,他们可不参与日常测试

    三是确定自动化测试成员在项目中的角色,一般自动化测试成员隶属于项目测试负责人,负责人同样跟踪其工作状态

    四是选择最简单 最重用的测试用例使用自动测试方法

    五是使用工具厂商提供的测试框架编写脚本,千万别单纯的录制/加校验点/回放,以开发出健壮的且重用性强的测试脚本

    六是有专人更新脚本,也有专人跟踪自动测试结果

    七是一般选择的测试工具品牌和缺陷管理工具品牌是同一厂商,以方便不同类型缺陷的集中管理

    G由于不同公司开发产品的特殊性,也许需要特殊类型的测试,如安全测试,甚至代码级单元测试等,这些需要酌情考虑测试用例的编写,以及测试的执行。

    ――软件验收阶段,除了提交软件测试评估报告(各种类型测试结果的评估都有报告)这些传统工作外,对于测试用例,此时要集中时间更新,更新整个测试周期中一切需要更新的内容,以方便未来新版本的测试,即便是项目软件——提交客户后没有新版本,那也需要后期维护,维护阶段需要重新测试某功能点,然而用例不准确,碰巧又是个新员工,那就死翘翘了!

    退一步说,如果您公司的测试部门经历一次这样重大的洗礼,有一个项目真正按照此原则实施一次,也必将对未来取得事半功倍的效果。

    总结:综上所述,我们得出结论——

    测试用例在测试中没起到应有的作用,是因为测试用例编写质量不高,覆盖不够,执行不利;

    测试执行时不遵循测试用例,执行后不更新用例库,是测试部门的整体工作流程不健全不规范;

    测试行业仍处在群雄逐鹿、百家争鸣的时期,芸芸纷说,不如从自身出发,确立最适合自我的解决方案,整顿自身的工作流程,那才是金玉良言的上上策!

  • (Quote)测试用例设计版块一些测试用例设计的帖子

    2007-06-15 11:18:40

  • QTP板块上的常用辅助工具

    2007-06-05 16:29:07

  • QTP,WR,LR下载

    2007-05-24 14:58:10

  • [Quote]QTP学习的一些技巧

    2007-05-24 13:46:32

    1.测试中我们使用QTP调试脚本的时候一般就是DEBUG或者MSGBOX察看一些信息,其实有时候也可以使用print来实现批量的察看信息但是不影响程序运行.
    运行脚本:
    a="100"
    print a
    ~~~~~~~~~~~~~~~~~~~~~~~~~
    2.
    datatable特定行的数据可以这样使用
    运行脚本:
    DataTable.GetSheet("Action1").GetParameter("test").ValueByRow(4)
    ~~~~~~~~~~~~~~~~~~
    3.Wait Seconds [, Milliseconds]
    可以精确到毫秒.
    ~~~~~~~~~~~~~~~~~~
    4.
    在自定义的function里面数组作为返回值.
    运行脚本:
    circuit = "399937"
    Function trimString(circuit)
    Dim holdArray(5)
    holdArray(0) = Left(circuit, 2)
    holdArray(1) = Right(circuit, 2)
    msgbox holdArray(0) 'showed 39
    trimString = holdArray' I get an out of range error here
    End Function
    dim myArray
    'here I want to assign the return array to another array
    myArray = trimString(circuit)
    ' and then call one element from it
    msgbox myArray(1)
    ~~~~~~~~~~~~~~~
    5.
    计算一个操作的时间.
    运行脚本:
    Browser("Browser").Page("Page").Image("getRates").Click
    var_StartTime = Timer
    Browser("Browser").Page("Page").Sync
    Browser("Browser").Page("Page").Check CheckPoint("Check1")
    var_EndTime = Timer
    intRespTime = round ((var_EndTime - var_StartTime), 2 )
    msgbox (intRespTime)

  • [Quote]QTP Timeout Settings

    2007-05-24 13:45:48

     

    1.      Object Sync Timeout:这是QTP在等待一个对象显示的时间

    具体设置方法: Test Settings, Run Tab, the “Object Synchronization timeout:” setting.

    请注意在8.x版本中单位是毫秒,而在9.x 就变成秒了。

    程序中设置: Setting(“DefaultTimeout”) [=milliseconds]

    2. Browser Navigation Timeout
    帮助里这样定义 “sets the maximum time (in seconds) that QuickTest waits for a Web page to load before running a step in the test”. 那和上面的Object Sync Timeout setting有什么区别的,MI没有说,我猜想是在测试一个显示很缓慢的页面的时候使用吧。针对Navigation而不是一个对,从脚本看:

    Browser(“Browser”).Page(“Page”).WebRadioGroup(“Name:=txt_Name”,”html tag:=INPUT”).set “Test”

    这可能是一开始Browser的等待时间吧。

    具体设置方法: Test Settings, Web tab, “Browser navigation timeout:” X “seconds”

    在程序中怎么实现还没有解决,谁可以帮助我?

    3. Default Load Time
    QTP help 这样定义Instructs QuickTest to add a specified number of seconds to the page load time property specified in each Page checkpoint.”. 很迷惑,按照帮助的理解就是检查点额外的等待时间,过了这个时间再没有出现检查的数据可能就会返回错误了。
    具体设置方法: Options, Web Tab, “Add” x “seconds to page load time”
    程序中设置: Setting(“DefaultLoadTime”) [=seconds]

    4. Activate Window
    定义“specifies the time (in tenths of a second) that QuickTest waits before it sets the focus on an application window when using the pointing hand to point to an object in the application (for Object Spy, checkpoints, Step Generator, Recovery Scenario Wizard, and so forth)”. 我一直使用的默认的值,挺好的。呵呵。
    具体设置方法: Options, General tab, “When pointing at a window, activate it after” X “tenths of a second”
    程序中设置,暂无。

    5. .Exists(Timeout)
    用的是毫秒作为单位.

    6.  .WaitProperty(x, y, Timeout)
    用的是毫秒作为单位.

    7. Wait seconds [, milliseconds]

    这个就是我们经常用的wait,不过后面可以选择毫秒可能有的人就不知道了。

     

     

    以上是我总结的一些QTP关于时间的设置的,很多概念自己也不算清楚,希望和大家一起在学习中进步。

     
  • (Quote)QTP中的descriptive programming

    2007-05-24 13:44:54

     

    【摘要】自动化功能测试是一种企业级的用于检验应用程序是否如期运行的功能性测试工具。通过自动捕获,检测,和重复用户交互的操作,能够辨认缺陷并且确保那些跨越多个应用程序和据库的业务流程在初次发 布就能避免出现故障,并且保持长期可靠运行。在市场上用的比较多的主要包括Mercury公司的WinRunnerQuickTest ProfessionalIBMRational Robot。笔者对于QuickTest Professional相对较为熟悉,希望有机会向大家逐步介绍QuickTest Professional中的一些要点及技巧。在本文里主要介绍了QuickTest Professional中的一项核心内容Descrīptive Programming,希望对大家有所借鉴和帮助。在文中,为了方便起见,将QuickTest Professional简称QTP(本文是基于Quick Test Professional V8.0而写)

    【关键词】

    描述性编程Descrīptive Programming

    功能测试Functional Test

    专家视图Expert View

    关键字视图Keyword View

    对象模型Object Model

    运行时对象Run-Time Object

    测试对象Test Object

    【正文】

    QTP功能测试基本方法

    我们简单介绍一下有关功能测试的基本方法,这实际上对于所有自动化功能测试产品来说都是一样的。一般情况下,用QTP来进行功能测试的基本方法主要包括三个主要阶段:

     

     

    1、创建测试或组建

    首先可以通过在应用程序或网站上录制会话,或者建立对象库并使用关键字驱动功能向关键字视图中手动添加步骤来创建测试或组件。在QTP里面我们可以通过两种方式添加步骤来创建测试或组件:

    • 在应用程序或网站上录制会话。
    • 建立对象库并使用这些对象在关键字视图或专家视图中手动添加步骤

    然后在在测试或组件中插入检查点,检查页面、对象或文本字符串中的特定值或特征,通过它可以标识网站或应用程序是否正常运行。或是通过用参数替换固定值扩展测试或组件的范围。提供数据表中的数据,定义环境变量和值,定义测试、组件或操作参数和值,或者使用QTP生成随机数字或当前用户和测试数据等。

    最后如果需要的话使用QTP中众多的功能测试功能来增强测试或组件或添加编写语句来实现更复杂的测试目标。

    2、运行测试和组建

    控制运行会话,帮助标识和消除测试或组件中的缺陷。使用单步执行单步跳过单步退出命令逐步运行测试或组件,或设置断点使测试或组件在预定点暂停。每当测试或组件在断点处停止时,可以在调试查看器中查看其变量的值。

    3、分析结果

    在运行测试或组件之后,通过两种方式可以查看其结果:在结果窗口中查看结果;自动报告在运行会话过程中检测到的缺陷,可能的话并上报到其他缺陷管理产品中。

    .试图与对象模型

    在介绍QTP中的Descrīptive Programming前,我们有必要先介绍一下ExpertView及在ExpertView里进行编码的一些基本知识。

    QTP里面提供了两种视图,第一种我们把它称为KeywordView(关键字视图,在早期的版本中称为TreeView),第二种把它成为ExpertView(专家视图),这两种视图分别是针对两种类型的人进行使用的。

    1KeywordView(关键字视图)

    通过关键字视图,QTP提供了一种模块化的表格格式创建和查看测试或组件的步骤。每个步骤在关键字视图中都是一行,这样用户可以轻松的修改任何一部分组成。

    在录制会话过程中,用户在应用程序上执行的每个步骤在关键字视图中记录为一行。例如,在51testing的页面上执行的下列三个步骤:

    • 用户名编辑框中输入 zhoda02
    • 密码编辑框中输入加密字符串 41c630a213508cd49eb35089db1b893144b9
    • 单击登录按钮。

    那么,关键字视图将包含下列行:

     

     

    很显然,关键字视图非常直观有效,使用的人可以很清晰的看到被录制对象的录制层次及运行步骤,比较适合那些对于业务操作流程熟悉的人员使用。但是,如果需要一些增强型的操作,那就需要切换到专家视图里进行了。

    2ExpertView(专家视图)

    QTP在关键字视图中的每个节点在专家视图中对应一行脚本。上面例子对应的脚本如下:(删除后一句是因为前后重复,一句可以说明问题)

    Browser("51Testing软件测试网:软件测试的专业网站").Page("51Testing软件测试网:软件测试的专业网站").WebEdit("username").Set "zhoda02"

    Browser("51Testing软件测试网:软件测试的专业网站").Page("51Testing软件测试网:软件测试的专业网站").WebEdit("password").SetSecure "41c630a213508cd49eb35089db1b893144b9"

    Browser("51Testing软件测试网:软件测试的专业网站").Page("51Testing软件测试网:软件测试的专业网站").WebButton("登录").Click

    对于QTP来说,其核心编码语言是Visual Basic scrīpt,因此,如果用户熟悉VBscrīpt,可以运用自如的添加和更新语句,并通过编程方式增强测试和脚本,而这一切必须在专家视图中完成。

    更为重要的是,有些操作是必须在专家视图中才可以完成的,例如:要处理动态对象、客户化报告、获取对象运行时的属性值(Run-time Value)等等,这些都必须通过专家视图中的VBscrīpt编码完成。

    然而,QTP里所有的操作都是基于对象进行的,所以我们必须对对象模型有一个基本了解,才可以在专家视图内进行Descrīptive Programming

    3、测试对象模型

    测试对象模型是一大组对象类型或类,QTP用这些对象类型或类来表示应用程序中的对象。每个测试对象类都有一个可以唯一标识属于该类的对象的属性列表,以及一组 QTP可以对其进行录制的方法。它包括测试对象(Test Object)和运行时对象(RunTime Object)。

    测试对象是QTP在测试或组件中创建的用于表示应用程序中的实际对象的对象。QTP存储有关该对象的信息,这些信息有助于它在运行会话期间标识和检查该对象。

    运行时对象是网站或应用程序中的实际对象,在运行会话期间执行针对该对象的方法。

    如果录制时执行应用程序的相应操作,则一般情况下QTP将完成以下操作:

    • 标识 QTP测试对象类(表示执行了操作的对象),并创建相应的测试对象
    • 读取应用程序中对象属性的当前值,然后将属性和属性值列表与测试对象一起存储。
    • 选择该对象的唯一名称,一般使用该对象某个重要属性的值。
    • 使用适当的 QPT 测试对象方法录制对对象执行的操作。

    例如,假定使用以下 HTML 源代码单击查找按钮:

    <INPUT TYPE="submit" NAME="Find" VALUE="Find">

    QTPl将单击的对象标识为 WebButton 测试对象。它将创建一个名为 Find WebButton 对象,然后为该 Find WebButton 对象录制下列属性和属性值,同时还会录制对WebButtionClick方法。

     

     

    在关键字视图及专家视图中显示内容分别为:

    查看(651) 评论(0) 收藏 分享 管理

  • QTP中的描述性编程

    2007-05-24 13:42:47

      当我们并不想QTP依靠对象库来识别对象时,我们就可以借用描述性编程的方式.把对象的属性及属性值直接搬到代码中去,QTP直接通过脚本中的这些属性及属性值就能识别到这个对象,而不必再去匹配对象库.总的来说,如果您希望在未存储在对象库中的对象上执行操作,则这种编程描述将是非常有用的。或者还可以使用编程描述在具有某些相同属性的多个对象上执行相同的操作,或者在其属性与运行会话期间动态确定的描述相匹配的对象上执行操作。比如:在我的<QTP参数化实例>文章中,已经运用过描述性编程了.由于参数化的时候受到了对象库的制约,所以也采用了描述性编程的形式,让要参数化的对象不再受到对象库的制约.

    Dialog("Login").WinEdit("Agent Name:").Set "mercury"
    Dialog("Login").WinEdit("Password:").SetSecure "45a1e193f9dac3bf91f3ba7c1dd250a48a33eabf"
    Dialog("Login").WinButton("OK").Click
    Window("Flight Reservation").Close

        对应的对象库,如图:

     

        然后我们把对象库中,这些对象的属性及属性值从对象库搬到脚本中,代码修改成为:


    Dialog("text:=Login").WinEdit("attached text:=Agent Name:").Set "mercury"
    Dialog("text:=Login").WinEdit("attached text:=Password:").SetSecure "4414d23c42046da1ea3a895f1518b9c476b2b225"
    Dialog("text:=Login").WinButton("text:=OK").Click
    Window("regexpwndtitle:=Flight Reservation").close

        把对象库中对象删除掉,如下图:

  • (转)QTP中读取Access数据

    2007-05-24 13:40:03

    以下是QTP脚本,目的是用来读取Access数据库中的数据,代码如下:

    Option explicit
    R0q:J:B0NOGqq94129Dim Cnn ,strDb,Rst,strCnn,ilen  '//
    定义变量
    n8keP.RYC[1]k94129strCnn="Provider=Microsoft.Jet.OLEDB.4.0;Ole DB Services=-4;Data Source=D:\test\calc.mdb" ' //
    将获得的连接字符串赋值到
    8f:AgdFH-K94129Set Cnn=CreateObject("ADODB.Connection") '//
    生成数据库连接对象
    Z#cP2n
    Bu1yw94129
    Cnn.Open strCnn   '   //
    打开数据库
    K R9N`IJ-j%[94129Set Rst=CreateObject("ADODB.Recordset")  '//
    生成记录集对象  51Testing软件测试网im9L#C
    T{:kJNS2p

    Rst.Open "select * from calc" ,Cnn  
    im*~1N‑l1X8k94129Do While Not  Rst.EOF 51Testing
    软件测试网(s0},p p PZ,V
       For iLen=1 to 3  '//
    我的表中只有3个字段,当然这种方法通用性不是很好51Testing软件测试网y~I bd[1]Z9Oe c
        Select Case iLen51Testing
    软件测试网)RQiI8a j]
    V{F}

          Case 151Testing
    软件测试网\mj8LsL
                  strDb=strDb&Rst.Fields.item(iLen)&" "
    {
    B [1z#_"M*|o­T Z$V(U94129
          Case 2
    ,J,pB c,ou94129              strDb=strDb&"+ "&Rst.Fields.item(iLen)&" "
    ({0D"|3G cG!V"x7}&Z94129      Case 3
    a(N)c Vx9u
    l[(Vg94129
                  strDb=strDb&"= "&Rst.Fields.item(iLen)51Testing
    软件测试网#`PA wY9r |j"h&w
        End Select
    9dO"S @7RK-F-Z5B%G1^94129   Next

    zMOJ L94129
       strDb=strDb&chr(13)
    .V}S
    Q%S,g94129
       Rst.MoveNext
    (u;t!y,o4]e5v$W J1}94129 Loop 51Testing
    软件测试网_4h)~lSV ] G'Yfzf
    Rst.Close51Testing
    软件测试网|M4L/R
    ~ {yO#K

    cnn.close51Testing
    软件测试网K&x)B-t3kB
    t8lL

    msgbox strDb51Testing
    软件测试网'^­p)T5`:F ~o@hL
    希望这对QTP新手找这方面资料时有点帮助.
  • [转载]不用checkpoint的Bitmap比较

    2007-05-24 13:38:36

      fColor2   =   mybmp2.Point(X,   Y)     
      if   fColor1<>fColor2   then     
      msgbox   "
    不一样!
    "   

      End   If   
      Next   'X
      Next   'Y

  • VBScript中SendKeys的妙用

    2007-05-24 13:37:18

    什么是VBscrīpt?

    VBscrīpt
    的全称是:Microsoft Visual Basic scrīpt Editon.(微软公司可视化BASIC脚本版). VBS(VBscrīpt的进一步简写)是基于Visual Basic的脚本语言,其不编译成二进制文件而是直接由宿主(host)解释源代码并执行简单点说就是你写的程序不需要编译成.exe, 而是直接给用户发送.vbs的源程序用户就能执行了.

    SendKeys 
    方法


    模拟键盘操作,将一个或多个按键指令发送到指定Windows窗口来控制应用程序运行, 
    其使用格式为:
    object.SendKeys(string) 

    “object”
    :表示WshShell对象
     
    “string”
    :表示要发送的按键指令字符串,需要放在英文双引号中。


    -----------------------------------
    1.
    基本键 

      一般来说,要发送的按键指令都可以直接用该按键字符本身来表示,例如要发送字母“x”,使用“WshShell.SendKeys "x"”即可。当然,也可直接发送多个按键指令,只需要将按键字符按顺序排列在一起即可,例如,要发送按键“happy”,可以使用 WshShell.SendKeys "happy" 

    2.
    特殊功能键 

      对于需要与ShiftCtrlAlt三个控制键组合的按键,SendKeys使用特殊字符来表示: 

      
    Shift---------WshShell.SendKeys "+" 
      
    Ctrl---------WshShell.SendKeys "^" 
      Alt---------WshShell.SendKeys "%"  (注意   这样使用时,不用大括号括起这些特殊字符。)

      由于“+”“^”这些字符用来表示特殊的控制按键了,如何表示这些按键呢? 只要用大括号括住这些字符即可。例如要发送加号“+”,可使用“WshShell.SendKeys "{+}"” 

    另外对于一些不会生成字符的控制功能按键,也同样需要使用大括号括起来按键的名称。

    例如要发送回车键,需要用“ WshShell.SendKeys "{ENTER}" ”表示;
    发送向下的方向键用“ Wshell.SendKeys "{DOWN}" ”表示。 

    Space---------WshShell.SendKeys " " 
    Enter---------WshShell.SendKeys "{ENTER}" 
    ←---------WshShell.SendKeys "{RIGHT}" 
    ↑---------WshShell.SendKeys "{UP}" 
    F1---------WshShell.SendKeys "{F1}" 

    按键                代码
        
    BACKSPACE     {BACKSPACE}, {BS}, 
     {BKSP}    
    BREAK         {BREAK}    
    CAPS LOCK     {CAPSLOCK}    
    DEL or Delete {Delete} 
     {DEL}    
    DOWN ARROW    {DOWN}    
    END           {END}    
    ENTER         {ENTER}
     ~    
    ESC           {ESC}    
    HELP          {HELP}    
    HOME          {HOME}    
    INS or Insert {Insert} 
     {INS}    
    LEFT ARROW    {LEFT}    
    NUM LOCK      {NUMLOCK}    
    PAGE DOWN     {PGDN}    
    PAGE UP       {PGUP}    
    PRINT SCREEN  {PRTSC}    
    RIGHT ARROW   {RIGHT}    
    SCROLL LOCK   {SCROLLLOCK}    
    TAB           {TAB}    
    UP ARROW      {UP}    
    F1 {F1}    
    F2 {F2}    
    F3 {F3}    
    F4 {F4}    
    F5 {F5}    
    F6 {F6}    
    F7 {F7}    
    F8 {F8}    
    F9 {F9}    
    F10 {F10}

    Tips:
    如果需要发送多个重复的单字母按键,不必重复输入该字母,SendKeys允许使用简化格式进行描述,使用格式为“{按键 数字}”。例如要发送10个字母“x”,则输入“WshShell.SendKeys "{x 10}"”即可。


    -----------------------------------
    按下F5刷新桌面 

    Dim WshShell,Path,i 
    Set WshShell = Wscrīpt.CreateObject("Wscrīpt.Shell") 
    WshShell.SendKeys "{F5}" 
    ---------------------------------------------------- 
    电脑的自动重启
     

    set WshShell = CreateObject("Wscrīpt.Shell") 
    WshShell.SendKeys "^{ESC}u" 
    WshShell.SendKeys "R" 
    ---------------------------------------------------- 
    启动任务管理器
     

    set WshShell = CreateObject("Wscrīpt.Shell") 
    WshShell.SendKeys "^+{ESC}" 
    ---------------------------------------------------- 
    QQ
    消息连发
     

    Dim WshShell 
    Set WshShell= Wscrīpt.createObject("Wscrīpt.Shell") 
    WshShell.AppActivate "bomb" 
    for i=1 to 60 
    Wscrīpt.Sleep 800 
    WshShell.SendKeys "What do you say" 
    WshShell.SendKeys i 
    WshShell.SendKeys "%s" 
    next 
    ---------------------------------------------------- 
    自动到百度搜索歌曲:
    white flag 

    Dim WshShell,Path,i 
    Set WshShell = Wscrīpt.CreateObject("Wscrīpt.Shell") 
    WshShell.Run("IEXPLORE.EXE") 
    Wscrīpt.Sleep 2000 
    WshShell.AppActivate "about:blank-Microsoft Internet Explorer" 
    WshShell.SendKeys "+{TAB}" 
    WshShell.SendKeys "
    http://mp3.baidu.com
    Wscrīpt.Sleep 800 
    WshShell.SendKeys "{ENTER}" 
    Wscrīpt.Sleep 3000 
    WshShell.SendKeys "white flag" 
    Wscrīpt.Sleep 800 
    WshShell.SendKeys "{ENTER}" 
    ---------------------------------------------------- 
    自动关机

    Dim WshShell
    Set WshShell=Wscrīpt.CreateObject("Wscrīpt.Shell")
    Wscrīpt.Sleep 2000
    WshShell.Run "shutdown -r -t 120"
    wscrīpt.sleep 6000
    WshShell.Run "shutdown -a"
    ---------------------------------------------------- 
    在记事本中输入Happy Birthday!并保存为birth.txt 

    Dim WshShell 
    Set WshShell=Wscrīpt.CreateObject("Wscrīpt.Shell") 
    WshShell.Run "notepad" 
    Wscrīpt.Sleep 1500 
    WshShell.AppActivate "
    无标题 - 记事本

    WshShell.SendKeys "H" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "a" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "p" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "p" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "y" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys " " 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "B" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "i" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "r" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "t" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "h" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "d" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "a" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "y" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "!" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "%FS" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "b" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "i" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "r" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "t" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "h" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "%S" 
    Wscrīpt.Sleep 500 
    WshShell.SendKeys "%FX" 
    ---------------------------------------------------- 
    制作能自动定时存盘的记事本
     

    '
    第一部分:定义变量和对象
     

    Dim WshShell, AutoSaveTime, TXTFileName 
    AutoSaveTime=300000 
    Set WshShell=Wscrīpt.CreateObject("Wscrīpt.Shell") 
    TXTFileName=InputBox("
    请输入你要创建的文件名(不能用中文和纯数字)
    ") 

    '
    第二部分:打开并激活记事本
     

    WshShell.Run "notepad" 
    Wscrīpt.Sleep 200 
    WshShell.AppActivate "
    无标题 - 记事本


    '
    第三部分:用输入的文件名存盘
     

    WshShell.SendKeys "^s" 
    Wscrīpt.Sleep 300 
    WshShell.SendKeys TXTFileName 
    Wscrīpt.Sleep 300 
    WshShell.SendKeys "%s" 
    Wscrīpt.Sleep AutoSaveTime 
    '
    第四部分:自动定时存盘
     
    While WshShell.AppActivate (TXTFileName)=True 
    WshShell.SendKeys "^s" 
    Wscrīpt.Sleep AutoSaveTime 
    Wend 
    Wscrīpt.Quit 

    ---------------------------------------------------- 

    自动死机
    o(∩_∩)o...

    DIM WSHSHELL 
    SET WSHSHELL=Wscrīpt.CreateOBJECT("Wscrīpt.SHELL") 
    'WSHSHELL.RUN " " 
    'Wscrīpt.SLEEP 1000 
    WSHSHELL.SENDKEYS "{ENTER}" 
    'Wscrīpt.SLEEP 1000 
    WSHSHELL.SENDKEYS "{ENTER}" 
    'Wscrīpt.SLEEP 1000 
    WSHSHELL.SENDKEYS "{ENTER}" 
    'Wscrīpt.SLEEP 1000 
    WSHSHELL.SENDKEYS "{ENTER}" 
    'Wscrīpt.SLEEP 1000 
    WSHSHELL.SENDKEYS "{ENTER}" 

    [/quote]

     

        再来执行脚本,QTP执行成功.这就是描述性编程.当然值得注意的是,如果父对象用描述性编程表示了,那么后面的对象都要用描述性编程表示了.:

    Dialog("text:=Login").WinEdit("attached text:=Agent Name:").Set "mercury"

        这边Dialog("text:=Login")用描述性编程表示了,那么WinEdit("attached text:=Agent Name:")就必须要描述性编程表示了.因为在对象库中,子对象是依靠父对象存在的.所以如果Dialog("text:=Login")这个父对象从对象库中删除了,那么后面的子对象也同时被删除了.反过来子对象删除就不影响父对象.所以子对象可以单独用描述性编程表示,而不需牵连其他对象.

    此文来源于51testing博客,转载请注明出处为51testing博客
    原始链接:
    http://blog.51testing.com/?26649/action_viewspace_itemid_2625.html

  • 使用QTP的一些技巧

    2007-05-24 13:13:08

    一.Action

    GLOBAL  SHEET:可在任何action中调用它。(相当于全局变量)
    CURRENT  ACTION  SHEET(LOCAL):只提供对于本ACTION的调用
    如果你用了一个共享的对象库那么你就不能选择LOCAL来存储存一个对象数据表参数。
    ACTION  TOOLBAR真到插入ACTION才会出现。VIEW>TOOLS>ACTION
    DELETE一个插入的可重复ACTION如果DELETE第一项:只是删除此ACTION的调用语句。此ACTION还存在语句。
    第二项:把此ACTION从TEST中完全删除。
    如果在一个从外面调用来的ACTION插入新的ACTION那么是直接插入它的后面而不能插入其中,因为它是只读的。

     每天多一点!

  • QTP中一些基础代码结构累积

    2007-05-24 13:04:57

     

    1.        生产随机数列

    第一种方法:

    randomize'更新反回的数据

    funcation rand(k,n)

    n=int((k-1)*rnd+1)

    rand=n

    end funcation

    第二种方法:

    n=randomnumber.value(1,255) 

    2.        当运行到表中的某一行,自动导出表中的所有数据

    row=datatable.getcurrentrow

    if row="5" then

      datatable.export("d:\data.xml")

    end if

    3.        webedit("txtpass").setsecure"sdsdf...."

    如果参数化密码,可以直接在数据表中写入未加密的密码,它会自动识别,即不用把setsecure改为set 

    4.        如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证

    if browser("web_name".dialog("dialog_name").exist(1) then

    //如果不出现=false

    error_message=browser("web_name".dialog("diaglog_name".static("用户密码错误!").getRoproperty("text")))

      if error_message<>(datatable.value("error_info")) then

            msgbox(error_message)

        end if

        browser("web_name").dialog("diaglog_name").close

    end if

    这里我总结了两点技巧:

      一是:对于dialog中,虽然提示信息对象名称是“用户密码错误”,但如果信息对象名称是“该用户不存在”,不用更改会自动识别,我想主要是录制第一遍时,“用户密码错误”只是让运行时能找到这个控制,而不管它是什么内容,因为在对象仓库中,text不是决定该对象的属性。

        二是:如果对于提示信息比较长的,可以用mid(error_message,n,m)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理。

    5.        在运行时,向某一个单元格赋值: datatable.value("kai",dtlocalsheet)="nanjing"

    datatable.value("num")只在global形式下的一种省略形式;完整形式是datatable.value("num",dtlocalsheet)

    ——取得某一具体行的值:

    datatable.setcurrentrow(n);

    msgbox(datatable.getsheet("global").getparameter("kai").Rawvalue)

    或者

    kk=datatable.Rawvalue("kai","action1")

    -------------

    for i=1 to 3

    DataTable.SetCurrentRow(i)

    DataTable.Value("A","Global")=I            //DataTable.SetNextRow

    next

    -------------

    ——在run-time期间,添加一个action和参数

    kk=datatable.addsheet("name").addparameter("kai","ddd"). name'/value 

    6.      

     

    with dialog("name")                                   //可以省好多代码,看着也简洁

    content=.wintreeview

    end with

     

    7.       

    wintreeview.select(item)                    (根是0,列表第一个也是0)

    wintreeview.getcontent

    wintreeview.getitem(整行)+";"+

    winlistview.getitem(行中的第一个字符段)

    wincheckbox("").set"off"'/on 

    8.        数据库检查点:

     

    sub getdata

    set con=createobject("adodb.connection")

    con.open("descrīption=mod;driver=sqlserver;server=hp\sqlserver;uid=sa;"&_

             "pwd=11111;APP=qtp;WSID=hp;database=MOD31" 

                                                  //sqlserver方式

    Con.open "DRIVER = {Microsoft Access Driver (*.mdb)};DBQ=D:\Testdb.mdb"

    //access方式

    set record=createobject("adodb.recordset")

    sql="select * from m3_program"

    //选择具体满足一条件的:sql="select* from m3_program where "

    record.open sql,con

    if(record("p_name")="kai") then

    num=num+1;

    end if          

    if(not record.eof) then

    record.movenext

    msgbox("p_name")

    end if

    record.close

    set record=nothing

    con.close

    set con=nothing

    end sub                                   //如果没有查到内容,在结果中不会报错,也不会弹出窗口

     

    9.       

    vbcr----chr(13)回车符

    vblf----chr(10)换行符

    vbcrlf----chr(13)+chr(10)结合

     

    10.    stel run has two ways

     

    11.    对于时间,日期等的格式检查(一种是正则表达式,另一种是输出对比,如果不好对比,用mid截取一部分对比)

     

    12.   

  • 软件使用-测试工具TestComplete篇

    2007-05-22 16:57:12

    1、简介
        (译)作为AQtest的后续产品,TestComplete是一个项目开发中的自动化测试工具。它能测试任何window应用程序,可以完全对项目代码中对象类进行存取,这些对象可用不同语言写成,包括VC++,VB,Delphi,C++ Builder,Java或.Net及web应用。用TestComplete,你的项目可以通过额外的脚本测试或项目本身的代码测试,或二者混合兼之。TestComplete完全支持单元测试,功能测试以及每日的回归测试。

    2、原理分析
        TestComplete分析操作系统中启动的进程,并将每个进程中的窗口或线程之类的东西称之为Window。一个应用进程可能有很多个Window,这可以通过TestComplete提供的Object Browser看的很清楚。之所以能够重复执行脚本,首先是能够在每次都找到相同的线程名称和window名称,如果不同的环境下无法保证他们的相同,TestComplete就没办法找到脚本执行的入口点。
        在如下脚本:
          var p, w
          p = Sys.Process("java", 2)
          w = p.Window("SunAwtFrame", "InterTrade Settlement System")

        操作系统可以认为是Sys, 具体线程为p,而操作的窗口为w, 如果录制脚本和测试时的环境不同,即p和w不同,那么无法进行下一步,必须手工改为与测试环境相同。
        保证了上述内容,然后,录制操作者的动作并生成脚本。其原理就是记录下操作者的IO操作,如鼠标和键盘的动作,并译成脚本。
        测试过程,挨个解释执行记录的脚本动作而已,如果是全键盘操作,比较好控制,如果有鼠标操作,因为无法保证测试和录制的鼠标有相同的控件定位,所以可能会失败。要全部用键盘操作才行。

    3、安装 
        现有版本: V2.04 和 V3.04(Trial Demo)
        注册码: User Name: CLUSTER 
                Company Name: BLiZZARD 
                Code: CLU!-BLZ!-61898056
        (V2.04 和V3.04均可用此注册码)
        工具厂商网址: http://www.automatedqa.com/

    4、安Settlement中键盘模拟鼠标操作
        在TestComplet录制脚本过程中,如果有用鼠标的操作,将使脚本的的重复执行具有大大的不可靠性(比如由于每次操作的界面定位不同,或不同机器的大小,或分辨率不同),因此必须用键盘完成所有的动作,这样的脚本才具有完全的可重复性。
        用键盘操作所有的动作,具体到Settlement系统中一些焦点移动的按键如下:

    TAB

    向下一个控件移动焦点,(控件的级别是相等的, 如在同一个grid的一行中,来回循环,不能跳到上一层)

    Shift+TAB

    向上一个控件移动焦点(控件的级别是相等的,同上)

    Ctrl +TAB

    向下一个控件移动焦点,(控件的级别不必相等的, 如在同一个grid的一行中,到最后一个可以跳出这一行)

    Shift+Ctrl+Tab

    向上一个控件移动焦点(控件的级别不必相等的,同上)

    Enter

    向下一个控件移动焦点或将触发事件,如打开搜索页面的图标,或触发事件并移动焦点到下一个控件

    ALT+↑(ALT+↓)

    用于选择展开下拉框的内容。下拉框中按Enter选择

    PageUp/PageDown

    对于较长的页面,显示焦点控件所在的位置,如果已经显示了当前焦点,按此键可能无效

    space

    当焦点为checkbox,按空格控件打勾或去掉勾

        对于特殊的几个控件,原则上可以直接输入,以免引起不必要的操作上的麻烦,如日期弹出页面、instrument和ClientAcc弹出搜索页面。

  • 创建Excell、保存结果、导出结果

    2007-05-22 16:51:54

    '*******************************************************************    
            Dim ExcellApp                                                    '<--As Excel.Application
            Dim excelSheet                                                   '<--As Excel.worksheet
            Dim workbook                                                     '<--As Excel.workbook
            Dim excelbook
            Dim a
            a=now
            a=Cstr(a)
            s = Utilities.StringReplace(a, ":", "-",3)
            s=mid(s,1,len(s)-3)
            Set ExcelApp = CreateObject("Excel.Application")
            Set ExcellApp = CreateExcel(result,myvar)
            ExcellApp.Activeworkbook.saveAs "C:\"+"????测试"+s+".xls"
            ExcellApp.Quit
            Set ExcellApp = nothing
     end sub
    '*******************************************************************

     Function CreateExcel(result,myvar)                                      '<--As Excel.Application
              Dim excelSheet                                                 '<--As Excel.worksheet
              Set ExcelApp = CreateObject("Excel.Application")               '<--Create a new excel Object
                  ExcelApp.Workbooks.Add                                     '<--创建表头
                  ExcelApp.Visible = True
              Set CreateExcel = ExcelApp
              Set NewSheet = ExcelApp.Sheets.Item(1)
                  row=1
                  NewSheet.Name = "NetTestTools测试结果"
                  NewSheet.Rows(1).Font.Bold = True
                  NewSheet.Columns("A:A").ColumnWidth = 40
                  NewSheet.Columns("B:B").ColumnWidth = 50
                  NewSheet.Columns("B:B").HorizontalAlignment = -4108
                  NewSheet.Columns("C:C").ColumnWidth = 10
                  NewSheet.Columns("C:C").HorizontalAlignment = -4108
                  NewSheet.Columns("D:D").ColumnWidth = 20
                  NewSheet.Columns("D:D").HorizontalAlignment = -4108
                  NewSheet.Cells(row,1)="测试项目ID序号"
                  NewSheet.Cells(row,2)="错误信息"
                  NewSheet.Cells(row,3)="测试结果"
                  NewSheet.Cells(row,4)="测试时间"
                  NewSheet.Cells(row,5)="备    注"
            '''''''''''''''''''''
        for i=2 to 72
              if  result(i-1)="" then                                          '<--写正确信息
                  ExcelApp.Application.Visible = True
                  ExcelApp.Windows(1).Visible = True
                  ' add a new Workbooks and a new Sheet
                  'Set NewSheet = ExcelObj.Sheets.Item(1)
                  Set NewSheet = ExcelApp.Sheets.Item(1)
                 'row=1
                  NewSheet.Name = "NetTestTools测试结果"
                  NewSheet.Rows(1).Font.Bold = True 
                  NewSheet.rows(i).font.colorindex=5
                  'NewSheet.rows(i).font.colorindex=5
                  'NewSheet.Cells(i,1)="ID"+cstr(j)
                  NewSheet.Cells(i,1)="ID"+cstr(i-1)+myvar(i-1)
              NewSheet.Cells(i,2)="测试已完成"
              NewSheet.Cells(i,3)="Pass"
                  NewSheet.Cells(i,4)=Now
                  'ExcelObj.Save
                 'ExcelObj.close
              else
                  ExcelApp.Application.Visible = True                        '<--写错误信息
                  ExcelApp.Windows(1).Visible = True
                  'add a new Workbooks and a new Sheet
                  'Set NewSheet = ExcelObj.Sheets.Item(1)
                  Set NewSheet = ExcelApp.Sheets.Item(1)
                 'row=1
                  NewSheet.Name = "NetTestTools测试结果"
                  NewSheet.Rows(i).Font.Bold = True
                  NewSheet.rows(i).font.colorindex=3
                  NewSheet.Cells(i,1)="ID"+cstr(i-1)+myvar(i-1)
              NewSheet.Cells(i,2)=result(i-1)
              NewSheet.Cells(i,3)="Fail"
                  NewSheet.Cells(i,4)=Now
                  'ExcelObj.Save
                 'ExcelObj.close
               end if    
        next
    End Function

  • 自动换行

    2007-05-22 16:49:11

            NewSheet.Columns("B:C").WrapText = 1
            NewSheet.Columns("B:C").Orientation = 0
            NewSheet.Columns("B:C").AddIndent = 0
            NewSheet.Columns("B:C").ShrinkToFit = 0
            NewSheet.Columns("B:C").MergeCells = 0
  • 如何使用Excel对象处理数据?

    2007-05-22 16:48:35


      Dim xl
      打开excel文件
      Function OpenExcelFile(strFilePath)
      Set xl = CreateObject("Excel.Application")
      xl.Workbooks.Open strFilePath
      End Function
      获得指定单元格数据
      Function GetCellData(strSheet,rwIndex,colIndex)
      GetCellData = xl.WorkSheets(strSheet).Cells(rwIndex,colIndex)
      End Function
      填充单元格数据
      Function PutCellData(strSheet,rwIndex,colIndex,varData)
      xl.WorkSheets(strSheet).Cells(rwIndex,colIndex) = varData
      End Function
      保存并推出
      Function SaveAndQuit()
      xl.Activeworkbook.save
      xl.Quit
      Set xl = nothing
      End Function
  • (Quote)基础代码交流贴(随机数)

    2007-05-22 16:47:27

    这两周我开始学习QTP测试我们的web服务了;大体的软件使用操作流程是懂了,但具体实施起来特别是代码的组织及函数应用还有一些困难,因为自己只会vb没学习vbscrīpt,所以想和大家交流一下代码等一些基础知识;呵呵,一起学习,加强记忆与应用
    1 生产随机数列
    第一种方法
    randomize'更新反回的数据
    funcation rand(k)
    n=int((k-1)*rnd+1)
    rand=n
    end funcation

    第二种方法
    n=randomnumber.value(1,255)

    2  当运行到表中的某一行,自动导出表中的所有数据
    row=datatable.getcurrentrow
    if row="5" then
      datatable.export("d:\data.xml")
    end if

    3
    webedit("txtpass").setsecure"sdsdf...."
    如果参数化密码,可以直接在数据表中写入未加密的密码,它会自动识别,即不用把setsecure改为set

    4 如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证
    if browser("web_name").dialog("dialog_name").exist(1) then'如果不出现=false
         error_message=browser("web_name").dialog("diaglog_name").static("用户密码错误!".getRoproperty("text")
       if error_message<>(datatable.value("error_info"))then
             msgbox(error_message)
          end if
         browser("web_name").dialog("diaglog_name").close
      end if
    这里我总结了两点技巧:
      一是:对于dialog中,虽然提示信息对象名称是"用户密码错误",但如果信息对象名称是“该用户不存在”,不用更改会自动识别,我想主要是录制第一遍时,“用户密码错误”只是让运行时能找到这个控制,而不管它是什么内容,因为在对象仓库中,text不是决定该对象的属性
        二是:如果对于提示信息比较长的,可以用mid(error_message,n,m)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

    5  datatable.value("num")只在global形式下的一种省略形式;完整形式是:
    datatable.value("num",dtlocalsheet)

    -----向某一列的单元格赋值:
    datatable.value("column_name",dtlocalsheet)="nanjing"

    -----取得某一行具体值:
    datatable.setcurrentrow(n)
    msgbox(datatable.getsheet("global").getparameter("column_name").Rawvalue)
    或者kk=datatable.Rawvalue("column_name","action1")

    ----在run-time时,动态添加表格与数据
    kk=datatable.addsheet("sheet_name").addparameter("column_name","value").name;

    7   wintreeview一些操作
    选择一个条目:wintreeview.select(item)'根是0
    根的名称:wintreeview.getitem(0)

    8   数据库检查点模块:
    sub database_check
    set con=createobject("adodb.connection")
    con.open "Descrīption=IBM_ODBC;DRIVER=SQL Server;SERVER=IBM;UID=sa;"&_
                     "PWD=123456;APP=Quick Test Pro;WSID=IBM;DATABASE=IBM_table"
    'access方式:con.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\test.mdb"
    'Orocle方式:con.open "DRIVER={Oracle in OraHome92};SERVER=CESHI;UID=CND_TEST;PWD=CND;DBQ=CESHI;DBA=W;APA=T;EXC=F;XSM=Default;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=Lo;BAM=IfAllSuccessful;MTS=F;MDI=Me;CSR=F;FWC=F;PFC=10;TLO=O;"
    set record=createobject("adodb.recordset")
    sql="select*from ibm_one_table"
    record.open sql,con
    DO
    if(record("ibm_table_column")="kai")then'//查找表格中有多少kai
    num=num+1;
    end if
    record.movenext
    loop until record.eof=true
    record.close
    set record=nothing
    con.close
    set con=nothing
    end sub

    9   换行符
        vbcr----chr(13)回车符// vblf----chr(10)换行符
        vbcrlf----chr(13)+chr(10)结合//type(chr(13)就相当于按了一上键盘上的enter

    10  Run from step有两种方式:
    在Keyword View模式会从本步骤运行到所有action结束
    在expert view模式仅会将本action运行结束

    11  由于对象属性原因,无法识别对象
    -----对于对象属性是变化的,可以参数化/或者用正则表达式
    -----报匹配多个对象错误,可以spy查看对象,添加一个该对象另一个唯一标识属性
    -----有时可以删除对象的变化的属性来解决识别问题
    ------对于多个完全相同的对象,可以采用添加index,location,createtime等特殊属性来识别
      (index:按照程序源码,绘制对象的先后标识对象,所以与其它相同对象是相互依赖,当其它对象发生
      变化后,原先的所有对象index属性要发生变化,开始是0;如index:=0;
            location:根据对象的位置进行确定,从上到下,从左到右;
      CreateTime:按照对象被浏览器打开的先后标识对象)
    ------另外换一种思维方式,采取等效的方法;比如用键盘代替鼠标或用操作系统本身特性去解决问题

    12  对系统文件的操作
    -------从系统的文件中获取信息及删除文件
      get_file_infor("c:\she.mpg")
       function get_file_infor(url)
        dim fso,f
        set fso=createobject("scrīpting.filesystemobject")
        set f=fso.getfile(url)
        f.name:f.size:f.type:f.datacreated'///获取文件信息
        fso.deletefile(url)'/////删除文件
       end function
    --------获取文件夹里所有文件信息
    get_folder_infor("c:\kai")
    function get_folder_infor(folder)
    dim fso,f,f1,n
    set fso=createobject("scrīpting,filesystemobject")
    set f=fso.getfolder(folder)
    set fc=f.files
    for each f1 in fc
    select case f1.name
    case"kai.mpg","she.mpg","dd.mp3"'//检查文件夹里是否含有这些文件
    end select
    next
    end function

    13   等待某个对象出现方法
    y=......waitproperty("visible",true,10000)

    14   防程序中断方法
    On error resume next
    On error goto handle

    15  数组的应用:
    name=array(1,2,"aa","bb")
    name(2)="aa"
    16  正则表达式应用模板
    进行日期YYYY-MM-DD的格式检查 :
    Function RegExpTest(patrn, strng)
      Dim regEx, Match, Matches      ' Create variable.
      Set regEx = New RegExp         ' Create a regular expression.
      regEx.Pattern = patrn         ' Set pattern.
      regEx.IgnoreCase = True         ' Set case insensitivity.
      regEx.Global = True         ' Set global applicability.
      Set Matches = regEx.Execute(strng)   ' Execute search.
      For Each Match in Matches      ' Iterate Matches collection.
        RetStr = RetStr & "Match found at position "
        RetStr = RetStr & Match.FirstIndex & ". Match Value is '"
        RetStr = RetStr & Match.Value & "'." & vbCRLF
      Next
      RegExpTest = RetStr
    End Function
    date_pattern="^((((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((01,3-9])|(1[0-2]))-(29|30)))))$"
    result_message=RegExpTest(date_pattern, inputbox("请你输入要检查的时间:"))'用其它正则表达式更改此处
    Select case result_message
    Case ""
             msgbox("你输入的日期格式与标准不匹配")
    case else  MsgBox(result_message)
    end select

    17   返回一个字符串在另一字符串中的位置
    instr(string1,string2)

    18   有时回放出现找不到对象时,可能不是由于你的代码问题,而是由于你的操作系统等设置问题;
    举例说明1:
    比如:你录制一个选择磁盘中的文件动作
    会录制为:
    .winlistview("  ").drap 46,99
    .winlistview("  ").draponitem "she.mp3"
    下次录制的时候,如果你的系统文件改为不显示扩展名,下次执行的时候,QTP就找不到she.mp3,只能找到she;
    举例说明2:
    有时由于不同操作系统以及不同的ie,导致有些窗口不能识别,比如在2000下弹出的网页对话框的标题是:
    “web对话框",而在2003上是”网页对话框"

    19  "is+*"类型function
    isarray'是否是数组
    isconnected'判断QTP是否连接到TD
    isdate'是否是合法的日期类型
    isempty'判断是否初始化
    isNull'判断是否为空值
    isNumeric'判断是否是数字型
    isobject'判断是否一个功能对象
    isready'判断设备是否准备就绪
    isRootFolder'是否是根目录

    20 Action之间的参数传递
    例如:在Action1中,有如下代码:
    out_str="This is out_string"
    RunAction "Action2",oneIteration,out_str
    在Acton2中,在其step->Action Properties中的,input参数栏,加入out_str后,
    msgbox(parameter("out_str")),就能正确显示参数了 

    21 Wscrīpt.Shell的一些应用
    set WshShell =CreateObject("Wscrīpt.Shell")
    WshShell.SendKeys "{ENTER}"     '模拟键盘进行操作
    WshShell.AppActivate "Calculator"             '启动应用程序

    22 获取对象属性名称用法:
    GetRoProperty----从应用程序界面上获取对象属性(即,是脚本运行时,获取的对象动态属性值)
               例如:获取对象库中index属性值,似乎只能用GetToProperty,因为应用程序界面上对象没有该属性,只是QTP为识别该对象创立的描述属性;
    GetToproperty----从对象库中描述对象的属性,静态值
    GetToProperties----获取用于标识对象的属性集;对于这个集合,有count等属性方法

    23 FireEvent的使用-
    可以对一个对象进行更复杂的操作
    如:FireEvent("onfocus")   '使一个控件获取焦点
         FireEvent("ondblclick")  '实现双击/也可以在事件设定中针对该对象事件响应  

    24 模板的应用
    -----新建一个文本,输入一些新建Action时常包含的信息,然后保存为ActionTemplate.MST文件,
     并复制到QTP/dat目录下;这样每次新建action都会包含固定的信息了;
    例如:
    '-------------------脚本说明---------------
    '产品版本:      __Build(  )
    '测试员:
    '编写日期:
    '测试功能:
    '脚本类型:
    '被测试对象初始状态:
    '进展程度:
    '基本思路:
    '主要功能函数:
    '历史修改:
    '没解决的问题:
    '--------------------脚本内容-------------

    25 在对象库中,两个对象有时不能通过更改属性或命名来达到两个对象完全一致的替换;
    在web-mod项目中,我在对象库里添加了一个自动含有index标识属性的对象,然后每次通过SetToproperty来改变
    index值,对对象进行数据驱动,使其操作另一个对象,但脚本始终操作原先index属性值的对象;后来,把该对象
    删除掉,重新添加一个不自动含有index标识属性的该类对象,然后,手工添加,index标识属性,后来脚本能正常 工作了,可见两次的对象属性完全一致,但形成方式不一样,导致的结果往往也不一样;

    26 childobject的应用
    childobject可以返回界面上满足条件的对象集合,而且与对象库里是否有这些对象无关,这就可以简化对象库;
    返回的对象集合的count方法可以返回对象个数,这就可以通过下标对单个对象进行操作;在出现index标识对象时
    可以进行运用
    如:Set m_WinCheck=Descrīption.Create()
          m_WinCheck("nativeclass").Value="Button"
          set All_WinCheck=Window("").Dialog("").Childobject(m_WinCheck)
          n=All_WinCheck.Count()
         for i=0 to n-1
          All_WinCheck(i).Set "ON"
         next
    再加三个

    27 Create Log File:

    Dim LOGFile, fso, MyFile

    LOGFile="C:\Log.txt"
    Set fso = CreateObject("scrīpting.FileSystemObject")
        If fso.FileExists(LOGFile) = False Then
               Set MyFile = fso.CreateTextFile(LOGFile, True)
               MyFile.Close
        end if
    Set MyFile = fso.OpenTextFile(LOGFile, 8, True)
    MyFile.WriteLine("")
    MyFile.WriteLine(" " & Cstr(Now) & " ---------------------------------------------------------")
    MyFile.WriteLine("LOG Information!")
    MyFile.Close
    28 数据输入输出方法
    数据输入输出的方法:
    1  ExecuteFile"e:\kk.vbs"
    2  Environment.LoadFromFile("e:\k.xml")
    3  Datatable.ImportSheet/Import
    4  GetData from DataBase
    5  Datatable autofill
    6  Action input/output
    7  Use GetxxProperty to get data from Object
    8  Use Some Function to Product data

  • QTP中一个关于Action的实例

    2007-05-22 16:45:07


        本例还是以QTP安装后自带的Flight Reservation为例来录制脚本.首先我们把登录程序系统,然后新建定单,再打开定单,最后关闭系统.分别录制成5个action,设置一个主的action为main来分别先后调用login(登录),new order(新建定单),open order(打开定单),logout(退出).

    注明:设置拆分action,选择菜单功能split Action .选择independent of each other为并列的两个action.选择Nested为主次的两个action.

    全部录制完所有action后,在main action中代码如下:

    RunAction "login", oneIteration
    RunAction "new order", oneIteration
    RunAction "open order", oneIteration
    RunAction "logout", oneIteration

    其中RunAction是一个调用action的函数,后面跟action名和要传递的参数.

    说明:

    RunAction ActionName, [Iteration , Parameters]


    在这里我再引入action之间参数传递.在login action中选择菜单选项,在action properties中设置两input参数分别先后为username 和 passwd.

    这样我们就通过RunAction "login", oneIteration,"mercury","mercury"  把这两个变量分别传给username 和passwd.这边的变量先后关系分别依次对应了action properties里input参数的先后关系.

    这样我们就可以在login action中调用这两个变量了.

    Dialog("Login").WinEdit("Agent Name:").Set Parameter("username")
    Dialog("Login").WinEdit("Password:").Set Parameter("passwd")
    Dialog("Login").WinButton("OK").Click


    下面再来实现从一个action中传出一个变量给另一个action.

    那么我们在new order 中选择菜单选项,在action properties中设置一个output参数为orderno

    Window("Flight Reservation").WinEdit("Order No:").Output CheckPoint("Order No:")

    通过上面这句话把生成的定单号的值存放到这个ouput参数中

    RunAction "new order", oneIteration,order
    RunAction "open order", oneIteration,order

    再靠main action中这个order变量来传递,这个变量正好对应着new order里的output参数.从new order中传出来,再把这个变量传给open order.当然在open order中还要同样设置input参数.和这个order变量对应起来.

    这样就可以在open order中使用这个变量了.

    Window("Flight Reservation").Dialog("Open Order").WinEdit("Edit").Set Parameter("orderno")

    当然其实两个action之间传递参数还可以更简单点.比如一个脚本中 datatable和环境变量都是全局的,在一个脚本中的任何action都能使用.所以可以借用这两个来传递.

    通过这个例子最主要讲的是两点,拆分action和action之间的参数传递

  • 551/3123>

    数据统计

    • 访问量: 41097
    • 日志数: 55
    • 图片数: 6
    • 书签数: 1
    • 建立时间: 2007-05-22
    • 更新时间: 2007-12-12

    RSS订阅