人的烦恼源于记性太好 忘记过去才能重新开始

发布新日志

  • QuickTestProfessional基本使用示例(转载)

    2008-06-15 22:53:05

    1          设置脚本间的间隔时间

    Wait(2),单位:秒

    2          循环语句while

    i=0

    do while(i<10)

    Window("Opera").Restore

    Window("Opera").WinObject("OperaWindowClass").Click 446,232

    Window("Opera").WinObject("OperaWindowClass").Click 461,278

    i=i+1

    loop

    3         循环语句for

    For i=1 to 3

           Window("Opera").Restore

    Window("Opera").WinObject("OperaWindowClass").Click 446,232

    Window("Opera").WinObject("OperaWindowClass").Click 461,278

    Next

    4          判断语句

    Do while(i<20)

    Browser("XX项目").Page("XX项目").Frame("wap").Link("啤酒").Click

    wait(2)

    Browser("XX项目").Page("XX项目").Frame("wap_2").Link("商铺详情").Click

    wait(2)

    i=i+1

    If i=5 Then

           Exit do

    End If

    Loop

    5          With语句

    Do while(i<20)

    With Browser("XX项目")

    .Page("XX项目").Frame("wap").Link("生活家居").Click

    .Page("XX项目").Frame("wap_5").Link("出租(火爆招租中)").Click

    .Page("XX项目").Sync

    With .Page("XX项目")

    .Frame("wap_6").Image("image").Check CheckPoint("image")'检查点

    .Frame("wap_6").Link("返回XX首页").Click

    .Sync

    .Frame("wap").Check CheckPoint("生活家居")'检查点

    End with

    End with

    i=i+1

    If i=3 Then

        i=21

    End If

    Loop

    6         检查点

    Browser("XX项目").Page("XX项目").Frame("wap").Link("生活家居").Click

    Browser("XX项目").Page("XX项目").Frame("wap_5").Link("出租(火爆招租中)").Click

    Browser("XX项目").Page("XX项目").Sync

    Browser("XX项目").Page("XX项目").Frame("wap_6").Image("image").Check CheckPoint("image")'检查点

    Browser("XX项目").Page("XX项目").Frame("wap_6").Link("返回XX首页").Click

    Browser("XX项目").Page("XX项目").Sync

    Browser("XX项目").Page("XX项目").Frame("wap").Check CheckPoint("生活家居")'检查点

    7           引用函数

    Function  hjq(i)

       msgbox("hjq")

    End Function

     

    Do while(i<20)

    '开始

    Browser("XX项目").Page("XX项目").Frame("wap").Link("啤酒").Click

    wait(2)

    Browser("XX项目").Page("XX项目").Frame("wap_2").Link("商铺详情").Click

    '详情

    i=i+1

    If i=3 Then

        i=21

    End If

    Call hjq(i)

    Loop

    8           引用action

    录制action1,在step->action properties中设置该actionreuseable action

    录制action2,在inser->call to exiting action,选择action1

    OK

    9           参数化

    keyword view中设置对象的value为参数,并设置值

    With Browser("XX项目_2").Page("XX项目")

           With .Frame("wap_2")

                  .WebEdit("key").Set "1"

                  .WebButton("").Click

           End With

           .Frame("wap_3").Link("重新搜索").Click

           With .Frame("wap")

                  .WebEdit("key").Set DataTable("p_Text", dtGlobalSheet)

                  .WebButton("").Click

           End With

           .Sync

    End With

    10       Vbs随机读取一行文本内容

    '随机读取文件中的一行

    randomize 

    set fso=createobject("scrīpting.filesystemobject")  '创建文件系统对象

    set a=createobject("scrīpting.dictionary")  '类似于二维数组

    set file=fso.opentextfile("D:\hjq.txt")  '打开文件

    do while file.atendofstream<>true 

    m=m+1  'm记录文件中文本行数

    a.add m,file.readline  'file.readline读取某行记录

    loop 

    file.close  '关闭文件

    h=int(rnd*m) 

    msgbox "" & h & ":  " & a(h) ,4096,"随机内容"

    msgbox "1:  " & a(1) ,4096,"内容"

    msgbox "2:  " & a(2) ,4096,"内容"

    msgbox "3:  " & a(3) ,4096,"内容"

    11       二维数组的使用

    set a=createobject("scrīpting.dictionary")  '类似于二维数组

    a.add 0,"返回XX首页"

    a.add 1,"返回XX首页"

    a.add 2,"返回XX首页"

    a.add 3,"返回XX首页"

     

    For i=0 to 3

     

    With Browser("XX项目").Page("XX项目")

           With .Frame("wap")

                  .WebEdit("key").Set "1"

                  .WebButton("").Click

           End With

           .Frame("wap_2").Link(a(i)).Click

           .Sync

    End With

    Next

    12       从文件读取文本,并赋予参数

    set fso=createobject("scrīpting.filesystemobject")  '创建文件系统对象

    set a=createobject("scrīpting.dictionary")  '类似于二维数组

    set file=fso.opentextfile("D:\hjq.txt")  '打开文件

    wait(2)

    do while file.atendofstream<>true

    With Browser("XX项目").Page("XX项目")

           With .Frame("wap")

                  .WebEdit("key").Set  file.readline

                  .WebButton("").Click

           End With

           .Frame("wap_2").Link("返回XX首页").Click

           .Sync

    End With

    loop 

    file.close  '关闭文件

    13       读取csv文件并分割字符串

    Dim aasplit

    set fso=createobject("scrīpting.filesystemobject")  '创建文件系统对象

    set file=fso.opentextfile("D:\hjq.csv")  '打开csv文件

    wait(2)

    Do while file.atendofstream<>true

        aasplit=split(file.readline,",")',分割字符串

     

           For i=0 to UBound(aasplit)

     

                  With Browser("XX项目").Page("XX项目")

                         With .Frame("wap")

                                .WebEdit("key").Set  aasplit(i)

                                .WebButton("").Click

                         End With

                         .Frame("wap_2").Link("返回XX首页").Click

                         .Sync

                  End With

                 

           Next

     

    loop 

    file.close  '关闭文件

    14       怎样识别弹出的web窗口和对象

    1,  进入object identification

    2,  enviroment中选择web

    3,  选择某个test object class,如browser

    4,  添加mandatory properties

    5,  确定

    6,  重新录制脚本

    7,  OK

    15       Vbs写文件

    set fs =createobject("scrīpting.filesystemobject")

    if (fs.fileexists("c:\hjq.txt")) then

    set f =fs.opentextfile("c:\hjq.txt",8)

    f.write chr(13)+chr(10)

    f.write "hello"

    f.write chr(13)+chr(10)

    f.writeline "beijing"

    f.close

    else

    set f=fs.opentextfile("c:\hjq.txt",2, true)

    f.writeblanklines 2 '写入2个空行

    f.write "china"

    f.close

    end if

     

    16       基本函数

    QTP的基本使用函数:

    1, 获取对话框相应的文字: GetVisible Text

    2, 查找相应的字符串: instr (1,查找目标字符串,所查找的字符串)

    3, 随机数的获取: Randomnumber.Value() cstr(int(Rnd*10)+1)

    4, 等待函数: Wait(秒数)

    5, 获取数组下标: UBound (数组名)

    6, 拆分数组: Split(MyString, ",", -1, 1)

    7, 可执行步骤: OptionalStep

    8, 报告信息: Reporter.ReportEvent 3, "Save Step", "Out of cycle!"

    9, 判断对话框是否存在: .exist

    10,事件过滤函数:Reporter.Filter=过滤条件(0123)0代表显示所有的errorwarning,1,显示error,2,显示waining,3,任何errorwarning都不显示。

    11,循环函数:do … loop untilfor…to… then next,while.

    12,数据表格:DataTable,向外赋值,Dim aa = DataTable.value(“CellingName”,”ActionName”).

    13,获得对象属性的三种方法GetTOPropertyGetTOProperties,GetROProperty,GetTOProperty获得程序中对象当前的属性,GetTOProperties获得当前属性所有集合,GetROProperty获得的是录制时对象所获得的属性。

    14,检查点方法check和输出指定属性值output

    15,函数Descrīption,可以获得某页面同标签的属性进行操作。

    16,函数nagative可以随便跳转页面到指定的URL

    17,函数Object可以获得当前页面同属性的控件。

    18,函数Focus可以让控件获得焦点,函数Blur则是失去焦点,click单击,dbclick双击。

    19,函数setAttribute可以设置控件属性,getAttribute可以获得属性。

  • 一、QTP识别对象的原理

    2008-05-31 00:10:09

    一、QTP识别对象的原理(by yabest, http://yabest.net)

    QTP里的对象有两个概念,一个是Test Object(简称TO),一个是Runtime Object(简称RO)。
    这两个概念从字面上不大好理解,也容易混淆。
    但从实际作用上来看,应该说TO就是是仓库文件里定义的仓库对象,RO是被测试软件的实际对象。

    QTP识别对象,一般是要求先在对象仓库文件里定义仓库对象,里面存有实际对象的特征属性的值。
    然后在运行的时候,QTP会根据脚本里的对象名字,在对象仓库里找到对应的仓库对象,
    接着根据仓库对象的特征属性描述,在被测试软件里搜索找到相匹配的实际对象,最后就可以对实际对象进行操作了。

    仓库对象TO一般在录制/编写脚本时加入仓库文件,它不仅可以在录制编写时进行修改,
    也可以在运行过程中进行动态修改,以匹配实际对象。

    和TO、RO相关的几个函数有:

    GetTOProperty():取得仓库对象的某个属性的值
    GetTOProperties():取得仓库对象的所有属性的值
    SetTOProperty():设置仓库对象的某个属性的值

    GetROProperty():取得实际对象的某个属性的值


    理解了TO的含义,你就可以自由的用SetTOProperty()定义TO,以灵活的操作RO

    比如有个测试任务,窗口上有很多待检查的记录,每条记录右边都有一个Check按钮,用来检查各条记录。
    记录个数不定,所以Check按钮个数也就不定,只有一个Edit显示记录个数。
    我们要对每条记录进行检查,也就是要点击每个Check按钮。
    但是Check按钮个数不定,不好录制,而且个数可能也很多(上百个),即使能一一录制,那也很麻烦。

    那我有一个好办法,只录制一个按钮对象,它设有两个特征属性 label=OK, index=0
    然后用下面的脚本,就可以完成测试

    buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
    For buttonIndex = 0 to buttonNum - 1
      JavaWindow("Test").JavaButton("Check").SetTOProperty("index", buttonIndex)
      JavaWindow("Test").JavaButton("Check").Click
    Next


    或者窗口上有New、Modify、Delete、Check等好几个按钮,要把这几个按钮一一按过去
    我在对象仓库里只设置一个按钮对象AnyButton,label特征属性值填任意值,然后用下面脚本执行测试

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "New")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Modify")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Delete")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Check")
    JavaWindow("Test").JavaButton("AnyButton").Click

    另外,QTP还支持脚本描述的方法来定义和访问对象,即不需要在仓库里定义,也能访问和操作实际对象
    ( Written by yabest,http://yabest.net )

    如上面两个任务,可以如下实现

    1. 不需要在仓库里定义Check按钮对象,直接用下面脚本来实现测试

    buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
    For buttonIndex = 0 to buttonNum - 1
      JavaWindow("Test").JavaButton("label:=Check", "index:="+CStr(buttonIndex)).Click
    Next

    2. 不需要在仓库里定义New、Modify、Delete、Check按钮对象,直接用下面脚本来实现测试

    JavaWindow("Test").JavaButton("label:=New").Click
    JavaWindow("Test").JavaButton("label:=Modify").Click
    JavaWindow("Test").JavaButton("label:=Delete").Click
    JavaWindow("Test").JavaButton("label:=Check").Click



    二、QTP操作对象的原理(by yabest, http://yabest.net)

    QTP为用户提供了两种操作对象的接口,一种就是对象的封装接口,另一种是对象的自身接口。

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


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

    具体格式如下:
      对实际对象的操作:
          对象.object.自身属性
          对象.object.自身方法()
          对象.GetROProperty("封装属性")
          对象.封装方法()

      对仓库对象的操作:
          对象.GetTOProperty("封装属性")
          对象.GetTOProperties()      ’获取所有封装属性的值
          对象.SetTOProperty("封装属性", "封装属性值")

    比如操作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只是封装了部分常用的自身接口嘛。
    所以我们在需要时,可以绕过封装接口,直接调用对象的自身接口。
    不过有些自身接口不够稳定,在实践中偶尔会出现问题,但是概率很少。
    封装接口有相应功能的话,就尽量用封装接口吧!
    ( Written by yabest,http://yabest.net )

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

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

    (注意:GetROProperty访问的是实际对象的封装接口,GetTOProperty访问的是仓库对象的封装接口,
                两者访问的都是对象的封装接口,即Object Spy窗口里选Test Object时显示的属性。
                不要以为GetROProperty访问的是自身接口,即Object Spy窗口里选Run-time Object时显示的属性。
                QTP里的Test Object/Run-time Object的概念太容易让人混淆了!
                它既用来区分仓库对象和实际对象,又用来区分对象的封装接口和自身接口。



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

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

    你可以拿这个做恶作剧,指着这个窗口逼问开发人员,JavaEdit对象哪去了?
    开发人员肯定瞪大眼睛看着这个窗口,当场翘掉!!!
Open Toolbar