发布新日志

  • Flight login

    2009-07-08 15:40:40

    自己写的记录一下。同时谢谢几位版主给我指出了错误所在。

    Dim istatus  
    Dim text1
    Dim text2
    Dim text3
    SystemUtil.Run "E:\QTP\samples\flight\app\flight4a.exe","","E:\QTP\samples\flight\app\","open"

    Dialog("Login").WinEdit("Agent Name:").Set DataTable("Username", dtLocalSheet)
    Dialog("Login").WinEdit("Password:").Set DataTable("pwd", dtLocalSheet)
    istatus=DataTable("status",dtLocalSheet)
    Dialog("Login").WinButton("OK").Click

    If  Dialog("Login").Dialog("Flight Reservations").Exist(10)Then
     If Dialog("Login").Dialog("Flight Reservations").Static("Incorrect password. Please").Exist then
      text1 = Dialog("Login").Dialog("Flight Reservations").Static("Incorrect password. Please").GetROProperty("text")
      If text1 = istatus Then
      Reporter.ReportEvent micPass, "失败",text1
            end if
     else if Dialog("Login").Dialog("Flight Reservations").Static("Please enter password").Exist then
      text2= Dialog("Login").Dialog("Flight Reservations").Static("Please enter password").GetROProperty("text")
       If text2 = istatus Then
      Reporter.ReportEvent micPass, "异常",text2
      end if
     else if Dialog("Login").Dialog("Flight Reservations").Static("Please enter agent name").Exist then
      text3= Dialog("Login").Dialog("Flight Reservations").Static("Please enter agent name").GetROProperty("text")
       If text2 = istatus Then
      Reporter.ReportEvent micPass, "异常",text2
      end if
     end if
     end if
    end if

    wait (2)

    Dialog("Login").Dialog("Flight Reservations").WinButton("OK").Click
    Dialog("Login").WinButton("Cancel").Click

    else Reporter.ReportEvent micPass, "成功","登录成功"
     Window("Flight Reservation").Close
     END IF

  • virtual object 学习

    2009-02-03 10:11:34

    在录制脚本中,有时在回放时会遇到某个对象不能识别,此时可以考虑设置虚拟对象来代替。将这些不能识别的对象定义为虚拟对象,并将它们映射到标准类,例如按钮或复选框。QuickTest 在运行会话过程中模拟虚拟对象上的用户操作。在测试结果中,虚拟对象显示时类似标准类对象。

    1、有时qtp不能识别双击,导致最后回放的时候,QTP不能完成Click操作,弹出报错信息.需要设置虚拟的button对象来代替它.
    2、QTP有时把button对象识别成了Image(图片)对象,导致最后回放的时候,QTP不能完成Click操作,弹出报错信息,需要设置虚拟的button对象来代替它.

    下面是整个虚拟对象的制作过程:

    1.选择“Tools > Virtual Objects > New Virtual Object”。或者,也可以在虚拟对象管理器“Tools > Virtual Objects > Virtual Object Manager”中,单击“NEW”。将打开虚拟对象向导。单击“下一步”。


    2.选择要将您的虚拟对象映射到的标准类(这里有六种对象类供你选择,分别是object,button,table,list,check box,radio button).这里我们要映射一个button对象,所以选择button.单击"下一步"


    3.单击“标记对象”。选择你要做虚拟对象的区域,拖动鼠标.尽量能覆盖整个你想替代的对象.


    4.在“标识对象使用”框中,选择您希望 QTP 标识和映射虚拟对象的方式。


    如果您想要 QuickTest 标识所有出现的虚拟对象,请选择“Parent only”。

    如果想要 QuickTest 仅标识一次出现的虚拟对象,请选择“Entire parent hierarchy"。

    这里我们选择默认的“Parent only”。

    5.指定虚拟对象的名称和集合。从集合列表中选择,或通过在“集合名”框中输入新名称来新建集合


    点击完成,整个虚拟对象就做好了.

    虚拟对象做好后,保存在虚拟对象管理器中.我们可以通过虚拟对象管理器来删除或禁用虚拟对象定义.

    选择“Tools > Virtual Objects > Virtual Object Manager”。将打开虚拟对象管理器。


    注意:如果希望 QuickTest 在录制时识别虚拟对象,请确保清除“选项”对话框的“常规”选项卡中的“录制时禁止识别虚拟对象”复选框。

  • executefile 函数

    2009-02-02 21:57:09

    executefile可以直接执行vbs文件

    例:executefile ("D:\test.vbs")

  • QTP场景恢复

    2009-02-02 10:36:08

    场景恢复可以用于对测试脚本在运行的过程中出现的异常,在预估计可能出现的异常状况下,添加对应的场景恢复,可以使脚本运行的更加畅通.

    场景恢复机制提供了四种类型的触发事件:弹出对话框、对象的特殊属性值、运行错误、应用程序失败。

    Post-recovery分6项:

    Repeat current step and continue:重复当前步骤然后继续向下
    Proceed to next step:处理下一步
    Proceed to next action or component iteration:处理下一个Action,或者组件的下一个循环
    Proceed to next test
    iteration:处理该测试的下一个循环
    Restart current test run:重新启动当前的测试
    Stop the test run:终止测试运行

    应用场景:还是拿Login来说.

    大家都知道Login当然有正确登陆有失败登陆的用例是吧?我有三个如下的数据:

    admin 正确

    kaka 错误

    lidia 正确

    密码都是1

    但是现在面临的问题是,kaka录入进去之后,被测系统就会反应,提示错误的用户名和密码,那下面的测试(lidia),

    怎么进行呢?

    解决方案就是使用QTP里面提供的恢复场景:

    在Resource-Recover Senarioa Manager,点击工具条上的new,而不是按钮上的new,不知道上面的那个是

    啥用?下面就会弹出一个说明如下图:

    这里描述一下是什么意思?恢复场景的使用大概是这个过程:

    1.定义触发事件,如本例中的弹出"不正确的用户和密码",所以选择popup window.

    2.指定Popup Winow 用那个手去指喽!指向那个不正确的用户和密码窗口.

    3.定义你的恢复操作.就是当发生错误的时候你想干嘛?手动的时候弹出"非正确的用户和密码"的时候只要按确

     确定又回到首页了.因此这里选择keyboard Or mouse opeation.

    4.接下来选择,Click Default Button OR press the Enter Key.

      因为弹出窗口中,是个消息提示框,默认选中确定按钮.

    5.把Addd another Recovery operation钩掉.再按下一步,这个不用我解释了吧!

    6.当你按了那个弹出框的确定之后怎么办呢?选择Proceed to next test iteration.

      因为我这个登陆操作是个Reuseable的哈!下一次迭代就是取lidia去登陆咯!

    7.接下来要选中Add scenaria to current test. 就是应用到当前测试咯!

    Oh,Run一下!好,弹出非正确的用户名密码了。等了几秒钟,卡!继续运行下一次迭代,成功了!Yeah!

    多少牛比轰轰人物叫嚣的恢复场景被我搞定了耶! Happy!

  • Reporter对象

    2009-02-01 18:04:58

    本文介绍了Reporter对象的几个鲜为人知的方法,利用LogEvent、SetContext、UnSetContext方法,可以实现日志的结构化、层次化写入,让你的QTP测试报告看起来更加有条理、分类清晰。

      
      QTP的日志其实有很多的缺点,尤其是当你的脚本依赖函数来执行的时候,因为函数执行时调用Reporter对象来写日志,只会顺序从上到下、扁平、不分类地写下去,如图1所示。

    图1  函数执行时调用Reporter对象写日志的问题

      而不像在Action中写日志一样,按一定的层次关系来写日志(例如根据调用的关系嵌套)。那么如何让函数调用Reporter对象来写日志时也具备一定的层次关系,让日志展现更加灵活、分类清晰呢?其实QTP的Report对象中暗藏了不少可利用的属性和方法。

    Report对象的“私家珍藏”

      在关键字视图通过InterlliSense查看QTP的Report对象时(如图2所示),可发现仅有3个属性、1个方法可用,其中最常用的是ReportEvent方法。

    图2  Reporter对象的公开方法和属性

      而实际上,QTP的Report对象还有其他的方法可用,这些方法并没有对外公开,例如可用LogEvent方法来在日志树中写入一个节点:

    '  使用Reporter对象的LogEvent写入新节点
    intContext = Reporter.LogEvent("User", dicMetaDescrīption, Reporter.GetContext)

      用SetContext方法把某个节点作为父节点,这样的话,后续写入的Log都将在这个父节点之下:

    ' 调用Reporter对象的SetContext把新写入的节点作为父节点
    Reporter.SetContext intContext

      如果要退出该节点,返回日志树的上一层,则可调用UnSetContext方法即可,如下脚本所示:

    '调用Reporter对象的UnSetContext,返回上一层
    Reporter.UnSetContext

    Report对象“解密”

      有了LogEvent、SetContext、UnSetContext这几个方法,我们就可以实现日志的结构化、层次化写入了,例如下面的例子所示:

    ' 用一个Dictionary对象来存储节点的信息
    Set dicMetaDescrīption = CreateObject("scrīpting.Dictionary")
    ' 设置节点的状态
    dicMetaDescrīption("Status") = MicDone
    ' 设置节点的名称
    dicMetaDescrīption("PlainTextNodeName") = "父节点"
    ' 设置节点的详细描述信息(可以使用HTML格式)
    dicMetaDescrīption("StepHtmlInfo") = "<DIV align=left><H1>这是一个拥有孩子的节点</H1><b>Hello!</b> How are you!.</DIV>"
    ' 设置节点的图标
    dicMetaDescrīption("DllIconIndex") = 210
    dicMetaDescrīption("DllIconSelIndex") = 210
    ' 节点图标从ContextManager.dll这个DLL文件中读取
    dicMetaDescrīption("DllPAth") = "D:\Program Files\HP\QuickTest Professional\bin\ContextManager.dll"
    '  使用Reporter对象的LogEvent写入新节点
    intContext = Reporter.LogEvent("User", dicMetaDescrīption, Reporter.GetContext)
    ' 调用Reporter对象的SetContext把新写入的节点作为父节点
    Reporter.SetContext intContext
    ' 后续写入的Log都将在这个父节点之下
    Reporter.ReportEvent MicPass, "Step1", "Step1 Pass!"
    Reporter.ReportEvent MicWarnning, "Step2", "Step2 Pass With Warnning!"
    Reporter.ReportEvent MicFail, "Step2", "Step2 Fail!"
    '调用Reporter对象的UnSetContext,返回上一层
    Reporter.UnSetContext
    ' 在父节点之外写Log
    Reporter.ReportEvent MicPass, "Case2", "Case2 Pass!"

      在这个例子中,我们首先用一个Dictionary对象来存储节点的信息,其中Status表示节点的状态,例如MicDone就表示完成状态;PlainTextNodeName表示节点的名称;StepHtmlInfo表示节点的详细内容,可以用HTML格式来写入;还可以用DllIconIndex、DllIconSelIndex、DllPAth这3个属性来表示节点的图标。

      然后使用Reporter对象的LogEvent把Dictionary中存储的信息写入一个新节点,再调用Reporter对象的SetContext把新写入的节点作为父节点,这样后续写入的Log都将在这个父节点之下,最后调用Reporter对象的UnSetContext,返回上一层,这样后续写入的Log将在这个父节点之外。

      这个例子的运行结果如图3所示。

    图3  脚本运行结果

    封装成可重用的函数

      可以把上面的代码封装成一个可重用的函数,以方便调用。方法如下:

      (1)首先在QTP中使用“Function Definition Generator”来定义一个名为“EnterNode”的函数。如图4所示。

    图4  定义函数EnterNode

      该函数实现的是把日志写入某个节点下,输入参数为NodeName(节点的名称),NodeContent(节点的描述信息)。

      函数的脚本如下:

    '@Descrīption 指定把日志写入节点下
    Public Function EnterNode(ByRef NodeName, ByRef NodeContent)
     ' 用一个Dictionary对象来存储节点的信息
     Set dicMetaDescrīption = CreateObject("scrīpting.Dictionary")
     ' 设置节点的状态
     dicMetaDescrīption("Status") = MicDone
     ' 设置节点的名称
     dicMetaDescrīption("PlainTextNodeName") = NodeName
     ' 设置节点的详细描述信息(可以使用HTML格式)
     dicMetaDescrīption("StepHtmlInfo") = NodeContent
     ' 设置节点的图标
     dicMetaDescrīption("DllIconIndex") = 210
     dicMetaDescrīption("DllIconSelIndex") = 210
     ' 节点图标从ContextManager.dll这个DLL文件中读取
     dicMetaDescrīption("DllPAth") = "D:\Program Files\HP\QuickTest Professional\bin\ContextManager.dll"
     '  使用Reporter对象的LogEvent写入新节点
     intContext = Reporter.LogEvent("User", dicMetaDescrīption, Reporter.GetContext)
     ' 调用Reporter对象的SetContext把新写入的节点作为父节点
     Reporter.SetContext intContext 
    End Function

      (2)然后再定义一个与“EnterNode”相应的函数“ExitNode”,如图5所示:

    图5  定义函数ExitNode

      ExitNode函数用于退出当前日志节点,需要与EnterNode配对使用,函数的脚本如下所示:

    '@Descrīption 退出当前日志节点(与EnterNode配对使用)
    Public Function ExitNode
      '调用Reporter对象的UnSetContext,返回上一层
      Reporter.UnSetContext
    End Function

      (3)有了EnterNode和ExitNode函数后,我们就可以像下面的例子一样使用EnterNode和ExitNode,实现日志记录的结构化、层次化写入:

    ' 进入节点
    EnterNode "父节点","<DIV align=left><H1>这是一个拥有孩子的节点</H1><b>Hello!</b> How are you!.</DIV>"
    ' 在节点内写Log
    Reporter.ReportEvent MicPass, "Step1", "Step1 Pass!"
    Reporter.ReportEvent MicWarnning, "Step2", "Step2 Pass With Warnning!"
    Reporter.ReportEvent MicFail, "Step2", "Step2 Fail!"
    ' 退出节点
    ExitNode
    ' 在节点之外写Log
    Reporter.ReportEvent MicPass, "Case2", "Case2 Pass!"

      该脚本首先调用EnterNode,创建一个"父节点",并自动进入该节点的层次下,然后使用普通的ReportEvent方法写日志,当需要退出该"父节点"时,就调用一下ExitNode,则后续的日志都在该节点之外写。

    小结

      本文介绍了Reporter对象的几个鲜为人知的方法,利用LogEvent、SetContext、UnSetContext这几个方法,可以实现日志的结构化、层次化写入,让你的QTP测试报告看起来更加有条理、分类清晰。

      不知道为什么QTP的帮助文档中没有列出这几个有用的方法,但是不管怎样,在我们揭开了Reporter对象的这些隐藏的方法后,我们就可以充分利用它们为我们服务,让我们的自动化测试脚本更加强大。

  • 用户体验测试

    2009-02-01 17:38:12

    检查默认焦点位置

            在进行界面易用性测试和用户体验测试时,我们会要求在打开某个界面时,默认把焦点定位到某个控件,方便用户做后续的操作,例如默认定位到某个输入框,方便用户能马上输入数据。

            如果用人工的方式进行检查的话,需要打开每个界面,观察当前光标的位置,检查是否定位到合适的位置上,这样会比较耗费时间。而如果采用自动化的测试方法,则可以利用控件的Focused属性当前是否为True,来判断焦点是否落在控件上。

            每一个控件都会有Focused属性,可以使用Windows API函数中的GetFocus函数来获取当前焦点所在的控件.

         GetFocus相对应的Windows API函数是SetFocus,用于把焦点设置到某个控件上。大部分的测试工具在实现焦点的检查和设置其实都是采用了上述过程的原理。例如在QTP中,则可以采用如下脚本来实现相同的功能:

    Dialog("Login").Activate

    ' 如果默认焦点不在Agent Name输入框,则提示错误

    If NOT Dialog("Login").WinEdit("Agent Name:").CheckProperty("focused","True" )Then

           Msgbox Dialog("Login").WinEdit("Agent Name:").GetROProperty("focused")

    End If

        这里的CheckProperty函数和GetROProperty函数是基本上可以在每个测试对象中使用的函数,其中CheckProperty类似于检查点,用于检查测试对象的指定属性是否等于指定的值,对于控件焦点,则是focused属性,属性值为True表示焦点落在控件上,属性值为False则表示焦点没有在控件上。

        GetROProperty用于获取测试对象运行时的值。通过指定focused属性,可以获取到控件的焦点属性。

    ····································

    什么是用户体验测试?

            用户体验是软件产品的使用者对产品的印象、感觉,同时也是用户既有的软件使用习惯和业务思维模型的综合反映。软件产品的用户体验好,则能让用户感到使用方便、易用、符合思维习惯。

            用户体验测试就是基于用户的使用习惯和思维模式出发,结合实际的业务场景,对软件产品的外观、操作方式等方面进行检查。在MSF的组队模型中,就专门有一个角色被称为“用户体验工程师”(User Experience),如图1所示。但是大部分公司不会设置一个专门的用户体验角色,而是由测试人员来担任这项工作。

    1  MSF的组队模型

    自动化的用户体验测试

            用户体验测试也叫可用性测试(Usability Testing)。可用性测试主要从使用的合理性和方便性等角度对软件系统进行检查,发现人为因素或使用上的问题。要保证在足够详细的程度下,用户界面易于使用;对输入值可容错、响应时间和响应方式合理可行、输出信息有意义、正确并前后一致;出错信息能够引导用户去解决问题;软件文档全面、正规、确切。

     

     

                                                       学习啊!感谢陈能技老师

  • 错误处理 on error resume next

    2009-01-13 17:33:23


    Window("Flight Reservation").Activate
    On Error resume next                 '如果代码有错的话,加上这句就直接可以运行下去。
    Window("Flight Reservation").ActiveX("MaskEdBox").Type "042509"
    Window("Flight Reservation").ActiveX("MaskEdBox").Check CheckPoint("MaskEdBox")
    Window("Flight Reservation").WinComboBox("Fly From:").Select "Denver"
    Window("Flight Reservation").WinComboBox("Fly To:").Select "Frankfurt"
    Window("Flight Reservation").WinButton("FLIGHT").Click
    Window("Flight Reservation").Dialog("Flights Table").Activate

    Window("Flight Reservation").Dialog("Flights Table").WinList("From").Select "14243   DEN   12:57 PM   FRA   01:41 PM   SR     $110.00"

    Window("Flight Reservation").Dialog("Flights Table").WinButton("OK").Click
    Window("Flight Reservation").WinEdit("Name:").Type "w"
    Window("Flight Reservation").WinEdit("Name:").Set "w"

    Dim i, b
    For i = 1 to 3
    Select Case i
        case 1 b= "First"
        case 2 b = "Business"
        Case 3 b = "Economy"
    End Select
    Window("Flight Reservation").WinRadioButton("First").SetTOProperty "text",b
    Window("Flight Reservation").WinRadioButton("First").Set
    Next

    Window("Flight Reservation").WinButton("Insert Order").Click
    Window("Flight Reservation").WinButton("Button").Click

     

     

Open Toolbar