好好学习编码技术、测试理论、英语。

发布新日志

  • QTP识别和操作对象的原理(转载)

    2007-03-29 15:00:32

    一.QTP识别对象的原理

    QTP要求先在仓库文件里定义仓库对象,里面存有实际对象的特征属性的值,
    运行的时候,QTP会根据仓库对象的特征属性描述,寻找到实际对象,然后操作实际对象。

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

    相关的几个函数有:

    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还支持脚本描述的方法来定义和访问对象,即不需要在仓库里定义,也能访问和操作实际对象

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

    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为用户提供了两种操作对象的接口,一种就是对象的封装接口,另一种是对象的自身接口。
    对象的自身接口是对象控件本身的接口,只要做过软件开发,使用过控件的人应该很清楚。
    对象的封装接口是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时,它显示的就是对象的封装接口(封装的属性和方法)

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

    原始链接:http://bbs.51testing.com/thread-13554-1-1.html

  • Description 对象用于编程描述

    2007-03-21 15:21:02

    将 Descrīption 对象用于编程描述
    使用 Descrīption 对象可以返回包含一组 Property 对象的 Properties 集合对象。Property 对象由属性名和值组成。然后,可以在语句中指定用返回的 Properties 集合代替对象名。(每个 property 对象都包含一个属性名和值对。)

    注意:默认情况下,添加到 Properties 集合的所有 Property 对象的值都将作为正则表达式处理。因此,如果希望输入包含特殊正则表达式字符(例如 *、? 和 +)的值,请使用 \(反斜杠)字符指示 QuickTest 将特殊字符作为文字字符处理。有关正则表达式的详细信息,请参阅了解和使用正则表达式。

    可以将 RegularExpression 属性设置为 False,以便将集合中特定 Property 对象的值指定为文字值。有关详细信息,请参阅《QuickTest Professional Object Model Reference》(英语版)的“实用程序”部分。

    要创建 Properties 集合,可以使用以下语法输入 Descrīption.Create 语句:

    Set MyDescrīption = Descrīption.Create()

    创建 Properties 对象(例如,以上示例中的 MyDescrīption)后,就可以输入语句,以便在运行会话期间在 Properties 对象中添加、编辑、删除或检索属性和值。这样,您可以在运行会话期间,使用动态方法确定哪个属性以及多少个属性应包含在对象描述中。

    在 Properties 集合中填充一组 Property 对象(属性和值)后,可以在测试语句中指定用 Properties 对象代替对象名。

    例如,您无须输入:

    Window("Error").WinButton("text:=OK", "width:=50").Click

    而可以输入:

    Set MyDescrīption = Descrīption.Create()
    MyDescrīption("text").Value = "OK"
    MyDescrīption("width").Value = 50
    Window("Error").WinButton(MyDescrīption).Click

    注意:在测试对象层次中的特定位置使用编程描述后,在相同语句中该位置的后面部分,必须继续使用编程描述。如果在层次中使用编程描述说明的其他对象的后面,您按对象库名指定了某个测试对象,则 QuickTest 将无法识别该对象。

    例如,您可以使用 Browser(Desc1).Page(Desc1).Link(desc3),因为该语句在整个测试对象层次中使用编程描述。

    您也可以使用 Browser("Index").Page(Desc1).Link(desc3),因为该语句从描述中的特定位置(从 Page 对象描述开始)开始使用编程描述。

    不过,您不能使用 Browser(Desc1).Page(Desc1).Link("Example1"),因为该语句对 Browser 和 Page 对象使用编程描述,但又试图对 Link 测试对象使用对象库名(QuickTest 尝试根据名称来查找 Link 对象,但无法在库中找到该对象,因为父对象是使用编程描述指定的)。

    使用 Properties 对象时,可以将变量名用于属性或值,以便根据运行会话期间检索的属性和值来生成对象描述。

    如果希望对多个对象使用编程描述,则可以在测试或组件中创建多个 Properties 对象。

     

  • 描述性编程(转载2)

    2007-03-21 15:19:40

    录制的脚本:

    Dialog("Login").WinEdit("Agent Name:").Type "YYYYYY"
    Dialog("Login").WinEdit("Agent Name:").Set "yyyyy"
    Dialog("Login").WinEdit("Password:").SetSecure "45e7bace1f2e4161d1f6108a1151235a46dde145"
    Dialog("Login").WinEdit("Password:").Type  micReturn
    Dialog("Flight Reservations").WinButton("确定").Click
    用描述性编程编写的脚本
    Dialog("text:=Login").WinEdit("attached text:=Agent Name:").Set "YYYY"
    Dialog("text:=Login").WinEdit("attached text:=Password:").SetSecure "45e7b79479d8c49df2749048f22ae14fd5437c8b"
    Dialog("text:=Login").WinButton("text:=OK").Click
    Dialog("text:=Flight Reservations").WinButton("text:=确定").Click

    当然值得注意的是,如果父对象用描述性编程表示了,那么后面的对象都要用描述性编程表示了.如:

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

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

     

  • 如何调用vbs

    2007-03-21 15:18:18

    假设c盘下有MyFuction.vbs这个脚本
    Function MessgeBox()
    msgbox "test!"
    End Function

    方法一
    ExecuteFile  "c:\MyFuction.vbs"
    MessgeBox()
    方法2
    选择菜单 test---〉settings---〉resourse
    点击加号,选择vb脚本的路径点击 ok
    在expert view 中输入
    MessageBox()

  • qtp 基础代码---转载

    2007-03-21 15:12:52

    qtp 基础代码---转载自51testing中的kai_top 网友。

    1 生产随机数列
    第一种方法

    CODE:

    [Copy to clipboard]

    randomize'更新反回的数据
    funcation rand(k,n)
    n=int((k-1)*rnd+1)
    rand=n
    end funcation

    第二种方法

    CODE:

    [Copy to clipboard]

    n=randomnumber.value(1,255)

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

    CODE:

    [Copy to clipboard]

    row=datatable.getcurrentrow
    if row="5" then
      datatable.export("d:\data.xml")
    end if

    3

    CODE:

    [Copy to clipboard]

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

    如果参数化密码,可以直接在数据表中写入未加密的密码,它会自动识别,即不用把setsecure改为set
    4
     如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证

    CODE:

    [Copy to clipboard]

     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形式下的一种省略形式;完整形式
    :

    CODE:

    [Copy to clipboard]

    datatable.value("num",dtlocalsheet)

    -----向某一列的单元格赋值:

    CODE:

    [Copy to clipboard]

    datatable.value("column_name",dtlocalsheet)="nanjing"

    -----取得某一行具体值:

    CODE:

    [Copy to clipboard]

    datatable.setcurrentrow(n)
    msgbox(datatable.getsheet("global").getparameter("column_name").Rawvalue)
    或者kk=datatable.Rawvalue("column_name","action1")

    ----run-time时,动态添加表格与数据

    CODE:

    [Copy to clipboard]

    kk=datatable.addsheet("sheet_name").addparameter("column_name","value").name;

    6  简化代码,明晰结构的方式with--end with 结构:

    CODE:

    [Copy to clipboard]

    with Dialog("name")
           c1=.button("b_name").click'//
    等价于Dialog("name").button("b_name").click
    end with

    7   wintreeview一些操作

    CODE:

    [Copy to clipboard]

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

    8   数据库检查点模块:

    CODE:

    [Copy to clipboard]

    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   换行符

    CODE:

    [Copy to clipboard]

    vbcr----chr(13)回车符
        vblf----chr(10)
    换行符
        vbcrlf----chr(13)+chr(10)
    结合

    10  Run from step有两种方式:

    CODE:

    [Copy to clipboard]

    Keyword View模式会从本步骤运行到所有action结束
    expert view模式仅会将本action运行结束

    11  对于属性是变化的,有时可以把该属性从识别对象里删除,来解决识别问题
    12  
    对系统文件的操作

    CODE:

    [Copy to clipboard]

    -------从系统的文件中获取信息及删除文件
      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   等待某个对象出现方法

    CODE:

    [Copy to clipboard]

    y=......waitproperty("visible",true,10000)

    14   防程序中断方法

    CODE:

    [Copy to clipboard]

    On error resume next
    On error goto handle

    15  数组的应用:

    CODE:

    [Copy to clipboard]

    name=array(1,2,"aa","bb")
    name(2)="aa"

    16  正则表达式应用模板

    CODE:

    [Copy to clipboard]

    进行日期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   返回一个字符串在另一字符串中的位置

    CODE:

    [Copy to clipboard]

    instr(string1,string2)

    18   有时回放出现找不到对象时,可能不是由于你的代码问题,而是由于你的操作系统等设置问题;

    CODE:

    [Copy to clipboard]

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

    19  "is+*"类型function

    CODE:

    [Copy to clipboard]

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

     

  • 描述性编程(转载)

    2007-03-21 15:04:33

    文章出处:www.51testing.com / 作者:周坚

    描述性编程(descrīptive programming

    1
    descrīptive programming概述

    通常情况下,当在录制一个操作时,QTP会将被操作对象加入到对象库里(Object Repository)。一旦对象存在于对象库里,我们就可以在专家视图里通过添加相关的对象方法来对该对象进行操作。我们可以通过引用层次型对象库里的对象描述(Object Descrīption)来添加相应的方法。

    因为QTP对象库中的每个对象都具有唯一名称,所以在引用时对象名是必须需要指定的。然后在测试运行期间,QTP在对象库中根据这个对象的名称和父对象来查找对象,并使用为这个测试对象存储的测试对象描述,在网站或应用程序中标识该对象。

    例如我们用QTP录制Yahoo Mail登录情况时我们需要输入用户名,于是在录制时我们就会录下一个WebEdit对象,它的缺省逻辑名为“login”,该编辑字段位于名为“Yahoo! Mail - The best” 的页面上,并且该页面在浏览器中使用名称Yahoo!进行录制。

    那么如果我们想要应用该对象,就可以在专家视图输入以下信息:

    Browser("Yahoo!").Page("Yahoo! Mail - The best").WebEdit("login").Set “xxx”

    或者我们也可以调用一些方法,获取改对象在运行时的对象名,如:

    Browser("Yahoo!").Page("Yahoo! Mail - The best").WebEdit("login").GetROProperty(“name”)

    然而,我们可以发觉到,上面的例子在处理对象时,对象已经存在于对象库里,因此我们可以应用这个对象的逻辑名。实际使用中,情况往往并非如此简单,我们经常会遇到很多在页面上动态产生的对象,换而言之,对象库里没有这些对象,我们也无从引用。因此我们必须采用其他的技术来完成这类操作,这也就是我们需要讲解的Descrīptive Programming

    为了满足上面提到的动态对象的处理问题,QTP允许用户通过将对象属性编码到测试脚本里来动态识别对象,这就是我们通常意义下称为的Descrīptive Programming。通过这种方式,我们可以指示QTP不通过引用对象库和对象名来对实际对象进行操作。具体操作中,我们只需要为QTP提供对象的一组属性和值,这样QTP就可以来识别相应的对象并对其进行操作。这相当于,告诉QTP要识别对象的一些关键特征,根据这些特征QTP就可以一一匹配然后识别出来这个对象。

    而且,更为重要的是,通过这种Descrīptive Programming的方式,还可以让QTP识别具有某些相同属性的对象。我们先来举个例子来看一下:我们假设当前的Windows系统中打开了若干的Yahoo主页面(多于一个),现在我们要关闭所有的正在浏览Yahoo主页面的浏览器。

    对于上面那个例子来说,我们先看一个简单一点的情况,假设只有且仅有一个Yahoo主页面:那么我们可以用下面的方法来

    Window("Text:=Yahoo! - Microsoft Internet Explorer").Close

    我们可以看到语句里我们要查找的对象是Window窗口标题为“Yahoo! - Microsoft Internet Explorer”,然后把它关闭,具体的语法说明我们稍后为解释。但是上面的语句仅仅适合前面提到的条件只有且仅有一个Yahoo主页面,如果有多个同样的窗口就会出错,原因是通过语句可以匹配到多个对象,而QTP不知道应该对哪个对象进行关闭动作。我们需要进一步的缩小匹配范围:

    Dim i

    i = 0

    while (Window("Text:="Yahoo!" - Microsoft Internet Explorer", "index:="&i).exist)

    Window("Text:=Yahoo! - Microsoft Internet Explorer", "index:="&i).close

    i = i +1

    wend

    这里我们可以看到,对于具有相同属性的对象,我们可以通过index参数来对其进行区别,第一个对象为index=0,第二个为index=1等等,依次类推。当然我们还可以通过CreationTimeLocation参数来定位对象,这里就不详细叙述了。

    通过上面的例子,我们对Descrīptive Programming有一个基本了解了,下面我们详细讲解一下Descrīptive Programming:在具体实现中,我们有两种类型的Descrīptive Programming方法。可以列出直接在测试语句中描述对象的属性和值的集合;或者向Descrīption 对象中添加属性和值的集合,然后在语句中输入Descrīption 对象的名称。下面我们分别举例介绍。

    2
    、直接在语句中输入编程描述

    通过多个指定描述对象的property:=value对,可以直接在语句中描述对象,这是最直接有效的方法。

    常规语法为:

    TestObject("PropertyName1:=PropertyValue1", "..." , "PropertyNameX:="PropertyValueX""} 

    TestObject - 
    测试对象的类。

    PropertyName:=PropertyValue - 
    测试对象的属性及其值。各个property:="value" 对之间应用逗号和引号分开。

    例如:以下语句指定Mercury Tours 页面中名为author且索引值为WebEdit 测试对象。当测试运行时,QTP 将查找具有匹配属性值的WebEdit 对象,并输入文本jojo

    Browser("Mercury Tours").Page("Mercury Tours").WebEdit("Name:="Author"", "Index:="3"").Set "Mark Twain" 

    我们也可以从从描述中的特定位置(从Page 对象描述开始)开始使用Descrīptive Programming

    Browser("Mercury Tours").Page("Title:="Mercury" Tours").WebEdit("Name:="Author"", "Index:="3"").Set "jojo" 

    此外,如果我们希望在在一个测试或组件中多次使用相同的Descrīptive Programming,则可以将创建的对象赋值给变量,这样使用会方便很多。

    例如:我们需要完成下面一系列操作

    Window("Text:=HyperSna").WinButton("Caption:=
    日期").Click

    Window("Text:=HyperSna").WinButton("Caption:=
    时间").Click

    Window("Text:=HyperSna").WinButton("Caption:=
    确定").Click

    那么,为了方便其见,我们可以将Window("Text:=HyperSna")赋值到一个变量,然后再使用,参见下面的代码:

    Set WinHyper = Window("Text:="HyperSna"") 

    WinHyper.WinButton("Caption:=
    日期").Click

    WinHyper.WinButton("Caption:=
    时间").Click

    WinHyper.WinButton("Caption:=
    确定").Click

    如果使用了VBscrīpt里面的With语句,还可以简化为以下代码:

    With Window("Text:="HyperSna"") 

    .WinButton("Caption:=
    日期").Click 

    .WinButton("Caption:=
    时间").Click

    .WinButton("Caption:=
    确定").Click

    End With 

    下面我们来看一个更为详细的例子,在QTP产品缺省安装里面自带了一个网上订机票的示例称为Mercury Tour,我们看一下在订票过程中何时需要用Descrīptive Programming

    首先登入系统后,如果需要订票,就要先搜索航班,此时系统要求输入订票乘客的数量,假设我们在第一次录制脚本时选择了1Passenger,并成功完成订票。然后,我们需要参数化乘客数量来测试订票系统,我们会发现回放会失败。原因在于,不同的乘客的数量导致在订票时需要输入每个乘客的姓名,而录制时,只输入了一个乘客的姓名。而乘客姓名的输入框是随着乘客数量的变化而动态生成的,我们不可能从对象库里得到没有录制的对象,因此必须使用Descrīptive Programming


    在录制单个乘客时,我们得到的录制语句是:

    Browser("Welcome: Mercury Tours").Page("Book a Flight: Mercury").WebEdit("passFirst0").Set "Michael"

    Browser("Welcome: Mercury Tours").Page("Book a Flight: Mercury").WebEdit("passLast0").Set "Wang"

    显然WebEdit("passFirst0")WebEdit("passLast0")是录制时产生的对象并存放到对象库里的。通过对象库,我们可以看到对象的属性如下

    系统对于发生多个FirstName时,命名规则是passFirst0passFirst1…依次类推。因此只要通过简单的Descrīptive Programming就可以完成动态FirstNameLastName的识别工作。这里我们假设参数化的乘客数已经赋值给intPassNum,下面是脚本中的关键语句:

    counter = 0

    For i = 0 to (intPassNum)

    Browser("Find a Flight:").Page("Book a Flight:").WebEdit("name:="passFirst""&i).Set "Michael"

    Browser("Find a Flight:").Page("Book a Flight:").WebEdit("name:="passLast""&i).Set "Wang"

    counter = counter + 1

    Next

    3
    、使用descrīption对象

    使用Descrīption 对象可以返回包含一组Property 对象的Properties 集合对象。Property 对象由属性名和值组成。然后,可以在语句中指定用返回的Properties 集合代替对象名。(每个property 对象都包含一个属性名和值)。

    要创建Properties 集合,可以使用以下语法输入Descrīption.Create 语句:

    Set MyDescrīption = Descrīption.Create() 

    创建Properties 对象(例如,以上示例中的MyDescrīption)后,就可以输入语句,以便在运行会话期间在Properties 对象中添加、编辑、删除或检索属性和值。这样,就可以在运行会话期间,使用动态方法确定哪个属性以及多少个属性应包含在对象描述中。

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

    数据统计

    • 访问量: 16364
    • 日志数: 25
    • 建立时间: 2007-03-08
    • 更新时间: 2007-10-09

    RSS订阅