朋友皆兄弟

发布新日志

  • QTP中的descriptive programming

    就是爱测试 发布于 2008-01-27 12:00:41

    【摘要】自动化功能测试是一种企业级的用于检验应用程序是否如期运行的功能性测试工具。通过自动捕获,检测,和重复用户交互的操作,能够辨认缺陷并且确保那些跨越多个应用程序和数据库的业务流程在初次发布就能避免出现故障,并且保持长期可靠运行。在市场上用的比较多的主要包括Mercury公司的WinRunner,QuickTest Professional和IBM的Rational 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(专家视图),这两种视图分别是针对两种类型的人进行使用的。

    1、KeywordView(关键字视图)

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

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

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

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

       

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

    2.ExpertView(专家视图)

    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 对象录制下列属性和属性值,同时还会录制对WebButtion的Click方法。

       

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

       

    Browser("Mercury Interactive").Page("Mercury Interactive").WebButton("Find").Click

    运行测试或组件时,QTP通过其测试对象类及其描述(一组用于唯一标识该对象的测试对象属性和属性值)来标识应用程序中的每个对象。测试对象及其属性和属性值的列表存储在对象库中。例如在上例中,QTP将在运行会话期间在对象库中搜索 WebButton 对象,通过名称 Find 来查找其描述。QTP根据找到的描述,在应用程序中查找 WebButton 对象,该对象带有 HTML 标记 INPUT、类型为 submit、值为 Find。找到对象后,它将对其执行 Click 方法。

    在这样一组对象模型的基础上,QTP为各类应用对象都提供了一组方法和属性,例如Web Objects,Windows Objects,SAPGUI Objects,ActiveX,Java等。下面是一些Web Objects的方法和示例:

    对象 方法
    Browser

    Check

    Frame

    Click

    Image

    Exist

    Link

    GetCellData

    Page

    GetProperty

    WebArea

    GetROProperty

    WebButtion

    Mouseover

    WebCheckBox

    RowCount

    WebEdit

    Select

    WebList

    Set

    WebRadioGroup

    SetProperty

    WebTable Submit

    例1:获取单元格中的值

    thisText = Browser(…).Page(…).Frame.(…).WebTable("sample").GetCellData(2,1)

    例2:获取图片的名称

    ObjectName = Browser(…).Page(…).Image("Find").GetProperty("Name")

    例3:检查某个对象是否存在,如果存在弹出对话框说明对象存在。

    If Browser("Browser").Page("Page").Applet("login.html").JavaEdit("username").Exist Then

    MsgBox("The object exists.")

    End if

    .描述性编程(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等等,依次类推。当然我们还可以通过CreationTime和Location参数来定位对象,这里就不详细叙述了。

    通过上面的例子,我们对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且索引值为 3 的 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。

    首先登入系统后,如果需要订票,就要先搜索航班,此时系统要求输入订票乘客的数量,假设我们在第一次录制脚本时选择了1个Passenger,并成功完成订票。然后,我们需要参数化乘客数量来测试订票系统,我们会发现回放会失败。原因在于,不同的乘客的数量导致在订票时需要输入每个乘客的姓名,而录制时,只输入了一个乘客的姓名。而乘客姓名的输入框是随着乘客数量的变化而动态生成的,我们不可能从对象库里得到没有录制的对象,因此必须使用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时,命名规则是passFirst0,passFirst1…依次类推。因此只要通过简单的Descrīptive Programming就可以完成动态FirstName与LastName的识别工作。这里我们假设参数化的乘客数已经赋值给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 集合中填充一组 Property 对象(属性和值)后,可以在测试语句中指定用 Properties 对象代替对象名。

    例如,假设我们需要完成以下一个操作:

    Window("Error").WinButton("text:=OK", "index:=1").Click

    我们可以通过Descrīption对象来实现同样的功能,参加下面的代码:

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

    MyDescrīption("text").Value = "OK"

    MyDescrīption("index").Value = 1

    Window("Error").WinButton(MyDescrīption).Click

    Set MyDescrīption = Nothing

    【小结】以上是对QTP中有关处理动态对象中的Descrīptive Programming的简单介绍,希望对大家能够有所帮助,就总体而言,如果能够熟练掌握Descrīptive Programming,那么有很多实际中的问题就可以迎刃而解。当然Descrīptive Programming只是QTP中的一个功能,QTP在实际功能测试中还有很多强大的功能,作为QTP学习的一个系列有机会我会一一介绍。

  • QTP 常用函数(转)

    lynmin 发布于 2008-01-30 16:09:09

    1.GetCellData函数 

      作用:获取单元格的值

      例:  rowCount = Browser("xxx ").Page("xxx ").Frame("xxx").WebTable("xxx").RowCount软件测试专业网站:51Testing软件测试网e6{k.X SO.x
    For counter = 1 To rowCount软件测试专业网站:51Testing软件测试网8S'\!~?%F2H x*Ifx
      text = Browser("xxx").Page("xxx").Frame("xxx").WebTable("xxx").GetCellData(counter,1)软件测试专业网站:51Testing软件测试网;Wl)[{1v X(YgP
      If (text = "xxx") Then
    2K%c3s.T#L!^9z.} S ~46301    counter = counter - 1
    .imw&a~p Y:\w;\0~46301    selectNO = "#" & counter软件测试专业网站:51Testing软件测试网`7J Pmd
        Browser("xxx").Page("xxx").Frame("xxx").WebRadioGroup("xxx").Select selectNO
    qLT8{y46301    Exit For
    (M:n j.K'P sEB46301  End If软件测试专业网站:51Testing软件测试网-q l)j;yl
    Next

    2.把值插入datatable里

      例:   datatable.setcurrentrow(i) 软件测试专业网站:51Testing软件测试网 R6AB7t m f
            datatable.value("name","Global")="name"软件测试专业网站:51Testing软件测试网0k"E*E5d'['z:~#b&h`;@
            datatable.value("passwd","Global")="passwd"

    3.用代码来启动浏览器

      Browser1 = "IE"
    -rw&\,PM(P'C0R:E7P+|"J7E46301  StartURL = "www.51testing.com"
    !o!r,] xT[46301  IF Browser1 = "IE" THEN 软件测试专业网站:51Testing软件测试网gtJi8K
         set IE = CreateObject("InternetExplorer.Application")软件测试专业网站:51Testing软件测试网Ft8_4O^!ZW-\.`&VF
         IE.Visible = true
    5s!uY(p-[46301     IE.Navigate StartURL
    u%Hwq"s+V46301  END IF软件测试专业网站:51Testing软件测试网"Xe$z#B pY
     

    4.ExecuteFile函数

      作用:ExecuteFile 可以直接执行vbs文件,而不需要将其导入resource中 软件测试专业网站:51Testing软件测试网2Oz|? X
           ExecuteFile FileName 软件测试专业网站:51Testing软件测试网*f s%TM*s3})k[,Mf
      说明:where FileName is the absolute or relative path of your VBscrīpt file.

      例:ExecuteFile("F:\test.vbs")

    5.Strcomp函数 

      作用:比较文本

      例:dim strtext1,strtext2,str ,str1,comp1
    B%B { u8crC9l46301     strtext1 = "xxx"
    +O8{ Tn m[46301     strtext2 = "xxx"
    +|%b xQ"mY#K(]46301     str = VbWindow("xxx").VbWindow("xxx").VbLabe1("xxx").GetTOProperty("text")软件测试专业网站:51Testing软件测试网:\d#a8AW g w ud6V&e
         str1= VbWindow("xxx").VbWindow("xxx").VbLabel("xxx").GetTOProperty("text")软件测试专业网站:51Testing软件测试网,C/` vLr$z-_ EE
         comp1=strcomp(strtext1,str,0)
    .k$nL#a%k0y6rJM*j%Z|46301     If  comp=0 Then
    -Z*S0s!i EGL(GY,h46301          msgbox “这两个串相等”
    XW1b_@ U:r(ODgr&c46301     else
    Al \4v%eGq"j46301       msgbox str软件测试专业网站:51Testing软件测试网Q#D$YB Hv dw-A
         End If 

    6.CaptureBitmap 

      作用:捕获屏幕

    7. GetROProperty

      作用:取对象属性值

      例:VbWindow("xxx").VbWindow("xxx").VbWindow("xxx").ActiveX("xxx").GetROProperty("TextMatrix(1,0)") 

    8.ExitAction - 退出当前操作,无论其循环属性如何。软件测试专业网站:51Testing软件测试网7^k7u9h(a oZ ~Iw
      ExitActionIteration - 退出操作的当前循环。软件测试专业网站:51Testing软件测试网?'_&t ^$n9Od
      ExitRun - 退出测试,无论其循环属性如何。软件测试专业网站:51Testing软件测试网*{)nM)b*D4[F}
      ExitGlobalIteration - 退出当前全局循环。


    R$iRF!bf|463019.如何使用Excel对象处理数据?
    7Z7C3[,ME3[d1anogP46301  Dim xl软件测试专业网站:51Testing软件测试网+q`^w_f#i
      打开excel文件软件测试专业网站:51Testing软件测试网 fh8j,e3Z#d@3^M7[M+u
      Function OpenExcelFile(strFilePath)软件测试专业网站:51Testing软件测试网*S(G)W {k%t#k0L.X"g1E$V
      Set xl = CreateObject("Excel.Application")
    8Q7CN!D@ Fz46301  xl.Workbooks.Open strFilePath软件测试专业网站:51Testing软件测试网} V3h ~ju(pI gq
      End Function软件测试专业网站:51Testing软件测试网h"N%WI ]q
      获得指定单元格数据
    (E%g8C+P-?O!r2qz;z46301  Function GetCellData(strSheet,rwIndex,colIndex)
    :PB-t?f2VD.Ug46301  GetCellData = xl.WorkSheets(strSheet).Cells(rwIndex,colIndex)软件测试专业网站:51Testing软件测试网:Zt^jUk"a8G
      End Function软件测试专业网站:51Testing软件测试网H6}*HeY
      填充单元格数据软件测试专业网站:51Testing软件测试网1yY5e*IJVq&l8iI
      Function PutCellData(strSheet,rwIndex,colIndex,varData)
    /{,Y%HLO-Kj ne j^46301  xl.WorkSheets(strSheet).Cells(rwIndex,colIndex) = varData软件测试专业网站:51Testing软件测试网&\:zIA1Lg a7z"V
      End Function软件测试专业网站:51Testing软件测试网 E*w'{O:~^0aCUk
      保存并推出软件测试专业网站:51Testing软件测试网'f\+oQ h#f/V@i
      Function SaveAndQuit()软件测试专业网站:51Testing软件测试网`&AAW!c!r D
      xl.Activeworkbook.save
    7WyY{KQ A46301  xl.Quit
    LG'r-b A?"m,M46301  Set xl = nothing软件测试专业网站:51Testing软件测试网0x4NJ|~%s6l:D
      End Function
    "p8Yqr(C,y,\-R46301

    10.连接sql数据库

      例:Dim res,cmd,sql软件测试专业网站:51Testing软件测试网8[&qb p.}m
         Set Res=createobject("adodb.recordset")
    S$u"Q6Y0B1dO D46301     Set Cmd=createobject("adodb.command")
    7Q;kijE t46301     Cmd.activeconnection="Provider=SQLOLEDB.1;Password=111111;Persist Security Info=True;User ID=sa;Initial Catalog=xhq;Data Source=192.168.191.142"  '这句话是连接数据库的数据源,要做修改软件测试专业网站:51Testing软件测试网~ RDO| M ~)jS3CW/K#b
        Cmd.CommandType = 1
    amW1Uw Nq46301    sql="selec t * from 表 where name=username"软件测试专业网站:51Testing软件测试网*z _g,^ o G0_#t|
        Cmd.CommandText = sql
    .J.~e6U,l:Cp$l46301    Set res = Cmd.Execute()软件测试专业网站:51Testing软件测试网'T D+]xg0R*uz"E
        Set res = nothing软件测试专业网站:51Testing软件测试网 n2GWU:c J
        Set cmd.ActiveConnection = nothing软件测试专业网站:51Testing软件测试网8G1e(D}+i"r+g2?x(u
        Set Cmd= nothing

  • QTP中几个截取字符串的函数

    neusoftiger 发布于 2008-02-20 13:13:14

    Left 函数(Right函数就是从右边开始算起)
    T%Y\w x+JW!xhg128649返回指定数目的从字符串的左边算起的字符。Left(string, length)
    ~U\o8^rG128649参数软件测试专业网站:51Testing软件测试网.c B+? Tp|Cr
    string:字符串表达式,其最左边的字符被返回。如果 string 参数中包含 Null,则返回 Null。
    .?N6u-tB&h{1`128649Length:数值表达式,指明要返回的字符数目。如果是 0,返回零长度字符串 ("");如果大于或等于 string 参数中的字符总数,则返回整个字符串。
    +n5N,Z$t1S2c3\128649例子:软件测试专业网站:51Testing软件测试网 FtBk#m9o5A
    Dim MyString, LeftString软件测试专业网站:51Testing软件测试网7w]g0E}:] ^0u/T8M/k@
    MyString = "VBscrīpt"软件测试专业网站:51Testing软件测试网7C)s9~ _0A'\ tn
    LeftString = Left(MyString, 3) ' LeftString contains "VBS".软件测试专业网站:51Testing软件测试网6ow s9Kzd
    ***********************************
    A6T?m G,y128649Mid 函数软件测试专业网站:51Testing软件测试网/qO2R.JY6}"? J$\J-q
    从字符串中返回指定数目的字符。软件测试专业网站:51Testing软件测试网+M!vYM4w(NT
    Mid(string, start[, length])
    B:dYa4]:I4j&Lq/K128649参数:软件测试专业网站:51Testing软件测试网 rb ~ b+pzby
    string:字符串表达式,从中返回字符。如果 string 包含 Null,则返回 Null。软件测试专业网站:51Testing软件测试网4WU#Wx)X-b
    Start:string 中被提取的字符部分的开始位置。如果 start 超过了 string 中字符的数目,Mid 将返回零长度字符串 ("")。软件测试专业网站:51Testing软件测试网{yn'[XG-bH
    Length:要返回的字符数。如果省略或 length 超过文本的字符数(包括 start 处的字符),将返回字符串中从 start 到字符串结束的所有字符。软件测试专业网站:51Testing软件测试网 t9M Hm3@ O
    例子
    &G.gid _;](K128649Dim MyVar软件测试专业网站:51Testing软件测试网hY+d kx#W1g?%h
    MyVar = Mid("VB scrīpt is fun!", 4, 6) ' MyVar contains "scrīpt".
    q!H7h1?qk |6F128649********************软件测试专业网站:51Testing软件测试网6ra&\^6\0n%o+p
    InStr函数(InStrRev函数相反从最后向前起)软件测试专业网站:51Testing软件测试网2j hz9F x|
    返回指定的字符串在另一字符串中最先出现的位置。
    l0X\a`"QD%{U'd128649InStr([start, ]string1, string2[, compare])软件测试专业网站:51Testing软件测试网:[To`l9cs l
    参数:软件测试专业网站:51Testing软件测试网 ]r2KrQv
    start:起始位置,默认从第一位软件测试专业网站:51Testing软件测试网 cTX"S["fO:\ F+y
    string1:主体字符串,从左向右查找。如果string1为 Null,则返回 Null。软件测试专业网站:51Testing软件测试网(h3ZNo)]dO
    string2:查找的字符串,如果string2为 Null,则返回 Null。找不到就返回0。
    R$Y1}^ A128649compare:0是二进制比较,1是文本比较。0为缺省值。个人感觉区别就是在大小写。软件测试专业网站:51Testing软件测试网]3fSw?
    例子
    #G}5xhKczh6P128649Dim SearchString, SearchChar, MyPos
    (ps6TX"|,A$m0P128649SearchString ="XXpXXpXXPXXP"   ' String to search in.软件测试专业网站:51Testing软件测试网_%@(F ?J
    SearchChar = "P"   ' Search for "P".软件测试专业网站:51Testing软件测试网:\w*Y\Z?1l
    MyPos = Instr(4, SearchString, SearchChar, 1)   ' A textual comparison starting at position 4. Returns 6.软件测试专业网站:51Testing软件测试网 O0D$IP:^ ^}%f t"z
    MyPos = Instr(1, SearchString, SearchChar, 0)   ' A binary comparison starting at position 1. Returns 9.   
    .}(k Y)N!yOr128649MyPos = Instr(SearchString, SearchChar)   ' Comparison is binary by default (last argument is omitted). Returns 9.软件测试专业网站:51Testing软件测试网?"y1_:R;~I
    MyPos = Instr(1, SearchString, "W")   ' A binary comparison starting at position 1. Returns 0 ("W" is not found).软件测试专业网站:51Testing软件测试网Q;fn2BR/J _?
    ******************
    0B0a-V2Z[b128649Split 函数
    ET,b&k Me+Tp128649
    在指定的 delimiter 参数出现的所有位置断开 String 对象,将其拆分为子字符串,然后以数组形式返回子字符串。软件测试专业网站:51Testing软件测试网,w$F^Ba;A
    Split(expression[, delimiter[, count[, compare]]])
    0z?(XY5sq#z7Ht3E128649参数
    dh^n%a0g;his128649expression:主体字符串,也就是要被拆分处的字符或字符串。软件测试专业网站:51Testing软件测试网~8KEZ9C3d
    delimiter:拆分元素,默认是(" ") 软件测试专业网站:51Testing软件测试网C1x R,o^|V
    count:Number [可选] 要放入数组中的项目数。
    #TK9sK u3D+m ]128649compare:0是二进制比较,1是文本比较。0为缺省值。软件测试专业网站:51Testing软件测试网a9R|9|c4v/nN
    例子
    m:b~?3|/ORUx128649Dim MyString, MyArray, Msg软件测试专业网站:51Testing软件测试网L8x+U6Mt9P$Z}/Z
    MyString = "VBscrīptXisXfun!"软件测试专业网站:51Testing软件测试网:h/n uM'p-@2G
    MyArray = Split(MyString, "x", -1, 1)
    'SW|8fH128649' MyArray(0) contains "VBscrīpt".软件测试专业网站:51Testing软件测试网Ji uw4NJ H*B
    ' MyArray(1) contains "is".软件测试专业网站:51Testing软件测试网p"LwW6R
    ' MyArray(2) contains "fun!".软件测试专业网站:51Testing软件测试网[jdp'Q1b5[6s
    Msg = MyArray(0) & " " & MyArray(1)软件测试专业网站:51Testing软件测试网z;rr;w!FQd S
    Msg = Msg   & " " & MyArray(2)软件测试专业网站:51Testing软件测试网yP{d%CM
    MsgBox Msg软件测试专业网站:51Testing软件测试网1s%o2ChJ9Jf3l c
  • "Cannot identify object" QTP不能识别对象问题的解决方案

    qicyt1812 发布于 2008-02-25 15:21:13Top 1 Digest 1

    "Cannot identify object" QTP不能识别对象问题的解决方案

    QTP疑难问题解答(不能识别对象)

    1.  运行错误:不能识别对象(Cannot identify object
    出现了这个错误时,就表示当前被测程序的窗口中没有符合条件的对象。
    出现这种错误,可能的原因有以下两种:
    1 对象此时在程序中没有显示或不存在。
    2)在程序中存在该对象,但是它的描述在后来发生了改变,导致与对象仓库中存储的信息不匹配,从而QTP无法识别对象。
    如果你正遇到“Cannot identify object”的问题,解决方法1.1
    1.1 如何去识别对象描述(Identifying Test Object Descrīption Problems
    如果你能在被测程序中看到对象,但仍出现了“Cannot Identify Object”错误信息,这就表示仓库中对象的描述与程序中对象的描述一定存在着差异。
    解决对象描述问题的第一步是找到差异,最简单的方法是将仓库中对象的属性值与程序中对象的属性值进行比较(仓库中对象的属性值可在Object Repository窗口中查看,程序中对象的属性值可用Object Spy功能查看。)
    比较仓库中对象的属性值与程序中对象的属性值的操作见1.3
    在完成比较后,是否发现存在差异?
    如果是,请参考1.4
    如果否,请参考1.5
    1.2 处理对象丢失问题(Solving Missing Object Problems
    在运行脚本时,QTP尝试进行某种操作,而该操作的对象在程序中却没有出现,出现这种情况的原因有以下几种:
    l           
    对象不再存在。对象已经被从程序中删除。
    解决方法:见1.2.1
    l           
    对象还没有装载。
    解决方法:见1.2.2
    l           
    当前的程序页面(或窗口)不正确,不是对象所在的页面(或窗口)。
    解决方法:见1.2.3
    l           
    前一个步骤没有正确执行。
    解决方法:见1.2.3
    1.2.1
    解决对象不再存在的问题
    如果对象已经不再在被测程序中存在,则应在脚本中修改或删除相关步骤。
    1.2.2
    解决对象装载超时的问题
    如果对象丢失的原因是因为没有足够的时间装载,尝试以下解决方案
    a.
    对于Web对象,增加Browser Navigation TimeoutFile>Setting>Web页签)时间。
    b.
    在包括该对象的步骤前使用Wait语句,让QTP在执行该步骤之前等待一段时间。
    1.2.3
    检查前面步骤的执行情况
    如果是因为打开了错误的页面(或窗口)导致对象丢失问题,或因为前一步骤执行错误导致对象丢失问题,则请按以下方法检查原因:
    a.
    如果怀疑在完成脚本后,被测程序又发生了改变,则检查对象的继承关系以及对象描述。参考1.1
    b.
    如果怀疑脚本错误,则检查脚本的每一个步骤。你可能是遗失了某个步骤,也可能是使用了不正确的方法或参数。
    1.3 测试对象的属性值与Run-time对象的属性值的比较(Comparing Test Object and Run-Time Object Property Values
    根据以下的步骤比较测试对象与Run-time对象的属性值:
    1)   
    进入Object Repository窗口(Resources>Object Repository),选择对象。
    2)   
    用笔记下对象的class以及它的各个属性及属性值。
    3)   
    打开被测程序,并打开包含被测对象的页面或窗口。
    4)   
    QTP中选择菜单Tools>Object Spy或点击Object Spy按钮,打开Object Spy对话框。
    5)   
    选择“Test Object Properties”选项。
    6)   
    点击右上角的按钮(带有手图标的),这时QTP窗口以及Object Spy对话框都被最小化。
    7)   
    在程序页面(或窗口)中点击目标对象,恢复Object Spy对话框,并在对话框中显示对象及其父对象(以树的形式显示),并在Properties页签中显示当前对象的属性及属性值。
    8)   
    这时Object Spy对话框的Properties页签中显示Run-time对象的所有属性,在此查看对象的class,以及它的属性及属性值,并将它与第2步中记下的内容进行比较。
    1.4 解决对象描述存在的问题(Solving Object Descrīption Problems
    如果发现仓库中对象的属性值与程序中对象的属性值存在不同,你应该判断这个不同是个别对象的问题,还是其它同类对象也存在相同的问题。
    是所有(或多个)同类对象都存在问题吗?
    如果是,则参考1.6
    如果否,则参考
    1.7
    1.5 关于父对象描述的识别问题(Identifying Parent Object Descrīption Problems

    对象的识别还与它所继承的父对象有关。
    如果你能在被测程序中看到对象,而且程序中对象的属性值与仓库中对象的属性值也是一致的,但仍然遭遇到了“Cannot identify object”错误,则这个错误可能与它的父对象有关(如仓库中父对象的属性值与程序中父对象的属性值不一致),也可能是仓库中的对象与程序中对象的继承关系不相同导致的。
    要判断是继承关系中的哪个父对象出现了问题,请尝试下面的方法之一:
    l           
    重新录制对象,比较新旧对象的父对象。
    欲了解如何完成比较,参考1.8
    l           
    对继承关系中的每个父对象,分别插入一个Exist语句,并运行该部分脚本。
    欲了解如果创建Exist语句,参考1.9
    注:你也可以使用Object Repository窗口中的Highlight in Application功能,在被测程序中定位对象。
    一旦找到了存在问题的父对象,接下来尝试以下方法:
    l           
    修复存在问题的父对象的描述。方法见1.4
    l           
    在专家视图的模式下,查找所有继承存在问题的实例并进行修正。
    举例:1.8.1
    1.6 解决某类对象的识别问题(Solving Object Identification Problems for a Test Object Class
    如果你发现某类对象的对象描述对于被测程序来说都不是很合理,或你预期到对象描述中的某属性值是经常变化的,你可以在Object Identification对话框中改变该类的识别属性的设置,或定义该类的Smart Identification设置并启用Smart Identification机制,这样QTP就可以唯一识别对象了。
    1.7    解决单个对象的描述问题(Solving Individual Test Object Descrīption Problems
    选择下列方法之一来解决对象的描述问题:
    l           
    如果被测程序中对象描述发生了改变,并且你也清楚改变的内容,并且该改变是永久性或长期性的,你可以直接手工修改仓库中对象描述中的相关属性值。
    l           
    如果被测程序中的对象的属性值依赖于前面的步骤或其它对象,则将该属性值参数化,这样就可以使用其它步骤的输出值为属性值。
    l           
    如果属性值的组成部分中,部分是固定的,部分是动态改变的,则可以将属性值设计为正则表达式。
    l           
    如果属性值是遵循某种规则变化的,或者是不可预期的,则从对象描述中移除该属性,并向对象描述中添加一个或多个属性以便于QTP进行对象识别。
    l           If you can only access the information on the property values during the run session, you can create and use functions that use programmatic Descrīptions to identify the object using property values retrieved earlier in the run session.
    l           
    如果在录制过程中对象是唯一的,但现在程序中出现了两个或多个描述相同的对象,但是它们在页面(或窗口)中的位置不相同,则应在Object PropertiesObject Repository窗口中,向对象描述中添加一个ordinal identifierindexlocation)。
    1.8 重新录制对象,以判断父对象描述是否存在问题(Re-recording an Object to Identify Parent Object Descrīption Problems
    根据下面的指引,来判断父对象的问题。
    通过重新录制对象,来判断它的父对象是否存在问题:
    1)
    打开浏览器或程序,来到包含被测对象的页面或窗口。
    2)
    在关键字视图模式,选择最后一个组件(component),或在专家视图模式,将光标放在最后一个脚本步骤的下面。
    3)
    点击Record按钮,或选择Automation>Record
    4)
    点击(或操作)页面或窗口中的目标对象。
    5)
    点击Stop按钮,或选择Automation>Stop,完成步骤添加。
    6)
    右击新添加的步骤,并选择Object Properties右键菜单。
    7)
    Object Properties对话框中,点击Repository,打开Object Repository窗口,并选中了新对象。注意记下该对象的继承关系。
    8)
    Object Repository窗口中找到旧的对象(即存在问题的对象),将它的继承关系与新对象的继承关系进行比较。
    通过比较,可以检查到新旧对象是父对象的描述存在不同,还是它们的继承关系根本就不同。
    a.
    如果是父对象的描述问题,则修改父对象的描述。参见1.4.
    b.
    如果是对象的继承关系不正确(即具有不同的父对象)引起的问题,则在脚本中找到所有使用该继承关系的实例,将它们替换为正确的继承关系。

    举例:参见1.8.1
    1.8.1
    举例
    假设有一个带有Frame的网站,你录制了一个操作针对Image对象“Poster”的操作步骤。在Object Repository窗口,你可以Image对象的继承关系如下所示:
    MyCompany
    Browser
          MyCompany
    Page
              Main(Frame)
                   Poster(image)
    当你运行脚本时,网页看起来没有什么不同,但是识别Image对象时却出现了“Cannot identiry object”的错误提示。当你重新录制操作步骤,然后在Object Repository窗口中查看新的Image对象时,发现该对象的继承关系如下所示:
    MyCompany
    Browser
          MyCompany
    Page
               Poster(image)
    从中可以看出,Frame已经从Web Page 查看(2062) 评论(1) 收藏 分享 管理

  • QTP培训总结

    fei.ge 发布于 2008-12-17 11:42:28

    1.启动

    SystemUtil.Run和InvokeApplication

    例子:

    SystemUtil.Run "D:\Program Files\HP\QuickTest Professional\samples\flight\app\flight4a.exe"

    InvokeApplication "D:\Program Files\HP\QuickTest Professional\samples\flight\app\flight4a.exe"

    SystemUtil.Run "iexplore.exe","www.baidu.com",,,3

    InvokeApplication "C:\Program Files\Internet Explorer\IEXPLORE.EXE http://www.google.cn/"

    2.设置环境参数,并读取

    1)手动设置:file-settings-environment,选择build in,添加参数和值,并可以导出为xml文件

    2)可以自己直接创建修改xml文件,格式如下:

    xml文件的格式为:

    ================================================

    <Environment>
     <Variable>
      <Name>UserID</Name>
      <Value>founder</Value>
     </Variable>
     <Variable>
      <Name>pwd</Name>
      <Value>112</Value>
     </Variable>
    </Environment>

    =================================================

    3)通过语句读xml文件,并设置为环境参数

    例子:

    Environment.LoadFromFile "G:\qtpscrīpt\peixun\test.xml"
    Dim tmp_ID,tmp_pwd
    tmp_ID= Environment.Value ("UserID")
    tmp_pwd= Environment.Value ("pwd")
    msgbox environment.ExternalFileName
    msgbox tmp_ID
    msgbox tmp_pwd

    4)优点:任何action可以调用。

    如:设置路径为环境参数,以后脚本转移了,直接修改xml里路径的值就可以了。(?待实践)

    3.导出QTP的EXCEL文件,读取默认格式的xls文件(有Global,Action1)

    例子:导出excel文件,读取文件,并读取具体字段

    Dim tmp_pwd
    Datatable.Export "G:\qtpscrīpt\peixun\test.xls"                                                
    Datatable.Import "G:\qtpscrīpt\peixun\test.xls"
    tmp_pwd = datatable.RawValue("Password","Action1")
    msgbox tmp_pwd

    4.读取自己定义的xls文件

    例子:读取自己定义的xls文件,取值

    自己定义的xls文件,取出,替换到ACTION1的值。
    Datatable.ImportSheet "G:\qtpscrīpt\peixun\test1.xls",1,"Action1"  
    '设置当前读取第几行     
    datatable.SetCurrentRow(2)   
    tmp_pwd=Datatable.RawValue("Password","Action1")                            
    msgbox tmp_pwd
    Dim tmp_user 
    tmp_user=datatable.RawValue("UserID","Action1")
    msgbox tmp_user

    5.显示当前执行excel的行数

    Dim tmp
    datatable.SetCurrentRow(2)
    datatable.SetPrevRow
    datatable.SetNextRow
    tmp=datatable.RawValue("row","Action1")
    msgbox tmp
    tmp=datatable.RawValue("row","Action1")
    msgbox tmp

    6.语句调用vbs函数

    ExecuteFile  "c:\my.vbs"
    (注:我的QTP9.5版本不行)

    7.for循环

    Dim i,j
    For i=1 to 10 step 5
     For j=1 to 10
      print"j."&j
     Next
    Next

    8.重写方法

    例子:

     Function MySet(obj,x)
       MySet=obj.set(x)
       msgbox"Myset"
     End Function

    RegisterUserFunc "WinEdit","Set","MySet"
    Dialog("Login").WinEdit("Agent Name:").Set "founder"
    UnRegisterUserFunc "WinEdit","Set"

    练习:代替click动作

    Function MyClick(obj,x)
      mySet=obj.click(x)
      msgbox"Myclick"
    End Function

    RegisterUserFunc "WinButton","Click","MyClick"
    Dialog("Login").WinButton("OK").Click
    UnRegisterUserFunc "WinButton","Click"

    9.输出值

    Dialog("Login").WinEdit("Agent Name:").Output CheckPoint("Agent Name:_4")
    Dim temp
    temp=datatable.RawValue("name","Action1")
    msgbox temp

    10.同步点

    Dim temp
    temp=Window("Flight Reservation").WinComboBox("Fly From:").Check( CheckPoint("Fly From:_2"))                  '?????????加+正则表达式??
    msgbox temp

    11.给action设置参数

    手动到Keyword View页面,对action右键-action properties-Parameters,添加参数

    msgbox parameter.Item ("userid")

    ps:调用Action的方法。。?

    12.描述性编程

    方法一

    sName="Login"
    Dialog("text:="&sName,"Class Name:=Dialog").WinEdit("attached text:=Agent Name:").Set parameter.Item ("userid")
    Dialog("text:=Login","Class Name:=Dialog").WinEdit("attached text:=Password:").SetSecure  parameter.Item("password")
    Dialog("Login").WinButton("OK").Click

    方法二

    set AgentName = Descrīption.Create()
    AgentName("attached text").Value = "Agent Name:"
    Set MyObj=Descrīption.Create()
    MyObj("text").Value="Login"
    MyObj("class name").value="Dialog"


    Dialog(MyObj).WinEdit(AgentName).Set parameter.Item ("userid")
    Dialog(MyObj).WinEdit("attached text:=Password:").SetSecure  parameter.Item("password")
    Dialog(MyObj).WinButton("text:=OK").Click

  • [转载]揭秘QTP的DeviceReplay对象

    jiangnanxinxi 发布于 2008-12-31 14:52:47

    原文:The Undocumented DeviceReplay(http://www.advancedqtp.com/2008/03/undocumented-devicereplay/www.advancedqtp.com

     

    不知道为什么HP的帮助文档中没有提供关于DeviceReplay的强大功能的信息描述。你可以在Java插件中却可以找到DeviceReplay的属性,但是对于那些不使用Java插件的人可能会觉得这个对象仅在Java程序的测试中可用。

    为什么要用DeviceReplay?
    有些时候我们需要针对界面做一些指定的动作,例如右键单击一个对象,使用功能键(Fx)来激活某些热键的功能,这时候就可以使用DeviceReplay对象,或者在Object.Set和Object.Type方法不生效时使用DeviceReplay。

     

    并且DeviceReplay在输入特殊符号以及不同语言的文字时会很有用,因为不需要安装指定的字体或改变键盘布局,这对于测试多语言环境的应用程序会非常有用。

     

    在鼠标操作方面,我发现DragDrop方法非常有用,可以使用它来执行拖拽的操作,把一个Item从一个Frame拖动到另外一个Frame,或者在应用程序之间拖动。

    Mercury.DeviceReplay对象
    Mercury.DeviceReplay对象用于模拟鼠标单击和移动,还有键盘输入等操作。要使用DeviceReplay,你必须确保被测试的应用程序(AUT)是处于激活状态的窗口。如果你想对某个对象执行一项操作,则该对象必须拥有焦点(focus)。对于Windows应用程序,可以使用Activate方法:

    Window( "W" ).Activate micLeftBtn

     

    如果想把焦点设置到某个指定的对象上,通常使用Click方法可以完成。

     

    对于Web环境的应用程序,Activate方法不被支持,因此可以使用下面的技巧来完成:

    hwnd = Browser( "B" ).GetROProperty( "hwnd" )

    Window( "hwnd:=" & hwnd ).Activate micLeftBtn

     

    通常可以使用FireEvent “onfocusin”或object.focus,例如WebEdit(“WE”).Object.focus或WebEdit(“WE”)。FireEvent “onfocusin”。

     

    在调用DeviceReplay对象的方法之前,你需要首先创建DeviceReplay对象:

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    Microsoft.VisualBasic.Devices.Keyboard类
    为什么我要在介绍DeviceReplay对象之前介绍这个.NET的类呢?DeviceReplay是一个强大的未被文档化的对象,但是有一定的局限性。其中一个局限就是不能判断一个Control键是否已经被按下。在输入一个大写字母之前,我们需要知道CAPS-LOCK键是否已经按下。在使用数字键盘之前我们需要检查NUM-LOCK键是否已经被按下。否则我们在切换键盘输入状态时可能得到的并不是我们想要的状态。

     

    Devices.Keyboard类提供了属性,可用于获取当前的键盘状态,例如当前什么键被按下了,并且提供一个方法用于向激活的窗口发送键盘敲击事件。

     

    几个有用的属性包括:

    AltKeyDown - 判断ALT键是否处于按下状态。

    CapsLock -  判断CAPS LOCK键是否处于打开状态。

    CtrlKeyDown - 判断CTRL 键是否处于按下状态。

    NumLock - 判断NUM LOCK键是否处于打开状态。

    ScrollLock - 判断SCROLL LOCK键是否处于打开状态。

    ShiftKeyDown - 判断SHIFT键是否处于按下状态。

     

    Set Keyboard = DotNetFactory.CreateInstance(

    "Microsoft.VisualBasic.Devices.Keyboard", "Microsoft.VisualBasic" )

    Print CBool( Keyboard.AltKeyDown )

    Print CBool( Keyboard.CapsLock )

    Print CBool( Keyboard.CtrlKeyDown )

    Print CBool( Keyboard.NumLock )

    Print CBool( Keyboard.ScrollLock )

    Print CBool( Keyboard.ShiftKeyDown )

     

    注意:在使用DotNetFactory时数据类型必须被转换

    System.Windows.Forms.Control 类
    DeviceReplay的另外一个局限是不能获取当前鼠标(光标)在屏幕的位置。而System.Windows.Forms.Control这个类定义了那些拥有视觉表现的控件的基类。

     

    通过MousePosition属性可以获取当前鼠标光标在屏幕坐标的位置。访问MousePosition属性时,可以返回代表鼠标光标位置的Point数据。

    我的鼠标在哪?
    Set ctlr = DotNetFactory.CreateInstance("System.Windows.Forms.Control")

    For i = 1 To 10

    Wait 2

    Print "1. X=" & ctlr.MousePosition.X & "; Y=" & ctlr.MousePosition.Y

    Next

    Mercury.DeviceReplay的方法
    SendString方法
    描述

    向激活的窗口发送一个或多个键盘按键,就像敲击键盘一样。

    语法

    object.SendString( str )

    参数

    object : Mercury.DeviceReplay对象。

    str : 敲击的字符串。

    返回值

    无。

    例子

    下面的例子会激活记事本(notepad)并输入一段字符:

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    ' ** this line always identifies the notepad window.

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    deviceReplay.SendString( "DeviceReplay" )

    Set deviceReplay = Nothing

    KeyDown方法
    描述

    模拟一个按键的按下并保持(相当于Win32的KEY_DOWN事件)。

    语法

    object.KeyDown( key )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    返回值

    无。

    例子

    下面的例子会激活记事本(notepad)程序并使用大写和小写的方式输入字符串。注意在发送第一个字符串时,SHIFT键保持被按下的状态:

    Const VK_SHIFT = 42

    Const VK_RETURN = 28

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    ' ** Typing uppercase

    deviceReplay.KeyDown VK_SHIFT

    deviceReplay.SendString( "devicereplay" )

    deviceReplay.PressKey VK_RETURN

    deviceReplay.KeyUp VK_SHIFT

    ' ** Typing in lower case

    deviceReplay.SendString( "devicereplay" )

    Set deviceReplay = Nothing

    提示

    在KeyDown后应该有相应的KeyUp方法的调用。

    KeyDown方法就像人工按下一个按键并保持按下的状态。

    KeyUp方法
    描述

    模拟通过键盘释放某个按下的按键。

    语法

    object.KeyUp( key )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    返回值

    无。

    例子

    下面的例子会激活并并使用热键CTRL+O来打开记事本(notepad)的菜单,然后用ESC键关闭对话框。

    Const VK_O = 24

    Const VK_CONTROL = 29

    Const VK_ESCAPE = 1

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    ' ** Typing uppercase

    Wait 1

    ' ** Opening the menu Ctrl + O

    deviceReplay.KeyDown VK_CONTROL

    deviceReplay.PressKey VK_O

    deviceReplay.KeyUp VK_CONTROL

    Wait 2

    ' ** Closing the menu

    deviceReplay.PressKey VK_ESCAPE

    deviceReplay.SendString "Menu Open, was closed."

    Set deviceReplay = Nothing

    提示

    KeyUp方法应该与KeyDown方法配对使用。

    多个KeyUp不会对应用程序造成影响。

    如果需要组合热键,仅需要像人工执行的方式一样即可。

    PressKey方法
    描述

    模拟通过键盘按下一个按键并立即释放。

    语法

    object.PressKey( key )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    返回值

    无。

    例子

    下面的例子会激活记事本并使用热键CTRL+O来模拟选择文件打开菜单,然后用ESCAPE按键关闭对话框。

    Const VK_O = 24 : Const VK_F = 33

    Const VK_CONTROL = 29 : Const VK_ESCAPE = 1 : Const VK_MENU = 56

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    Wait 1

    ' ** Opening the menu Alt + F + O

    deviceReplay.PressKey VK_MENU

    deviceReplay.PressKey VK_F

    deviceReplay.PressKey VK_O

    Wait 2

    ' ** Closing the menu

    deviceReplay.PressKey VK_ESCAPE

    deviceReplay.SendString "Open menu was closed."

    Set deviceReplay = Nothing

    PressNKeys方法
    描述

    模拟通过键盘多次按下一个按键并立即释放。

    语法

    object.PressNKey( key, N )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    N:重复的次数。

    返回值

    无。

    例子

    例1 – 美国的州

    Option Explicit

    Const VK_RETURN = 28 : Const VK_F = 33 : Const VK_O = 24

    Const VK_TAB = 15 : Const VK_F5 = 63

    Const VK_CAPITAL = 58 : Const VK_NUMLOCK = 69

    Const VK_SUBTRACT = 74 : Const VK_MULTIPLY = 55

    Const VK_MENU = 56

    Dim deviceReplay

    Private Sub SetupKeyboard()

    Const CLASS_NAME = "Microsoft.VisualBasic.Devices.Keyboard"

    Const ASSEMBLY = "Microsoft.VisualBasic"

    Dim Keyboard

    Set Keyboard = DotNetFactory.CreateInstance( CLASS_NAME, ASSEMBLY )

    If CBool( Keyboard.CapsLock ) Then

    deviceReplay.PressKey VK_CAPITAL

    End If

    If CBool( Keyboard.NumLock ) = False Then

    deviceReplay.PressKey VK_NUMLOCK

    End If

    Set Keyboard = Nothing

    End Sub

    Private Sub SetupNotepad()

    deviceReplay.PressKey VK_MENU

    deviceReplay.PressKey VK_O

    deviceReplay.PressKey VK_F

    deviceReplay.SendString "Courier New"

    deviceReplay.PressKey VK_TAB

    deviceReplay.PressKey VK_TAB

    deviceReplay.SendString "14"

    deviceReplay.PressKey VK_RETURN

    Wait 1

    End Sub

    Private Sub PrintRow( ByVal state, ByVal usps, byVal capital )

    deviceReplay.SendString state

     

  • QTP数据表数据库操作(z)

    点点滴滴 发布于 2008-12-19 14:55:56

    1、Datatable方法GetRowCount
       DataTable.GetSheet("Action1").GetRowCount   //获取总行数
    使用如:
    CountNum=DataTable.GetSheet("Action1").GetRowCount

    2、Datatable方法SetNextRow
       DataTable.GetSheet("Action1").SetNextRow     //取得下一行
       datatable.setcurrentrow(n)   //取得某一行

    3、Datatable方法getcurrentrow    //获得当前行数
       例如:datatable.getcurrentrow

    4、获取datatable值
       4.1 DataTable("p_Text", dtLocalSheet) //取得datatable中参数名称为:p_Text的值
       4.2 DataTable.GlobalSheet.GetParameter("p_Text").Value   //获取参数值方法和DataTable("p_Text", dtLocalSheet)一样
       例如:xname为变量,dim xname
       xname=DataTable("p_Text", dtLocalSheet)
       xname=DataTable.GlobalSheet.GetParameter("p_Text").Value

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

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

    6、字符转换Cstr
       dim mm
       Cstr(mm)

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

    8、如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证
    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)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

    9、数据库检查点模块:
    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

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

    11、for方法1,参数化时选择:dtLocalSheet
    Dim CountNum
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    For i=0 to CountNum-1
    ----xunhuanti------
    DataTable.GetSheet("Action1").SetNextRow    //使用SetNextRow方法
    Next

    12、for方法2,参数化时选择:dtLocalSheet
    dim countNum
    countNum = DataTable.GetSheet("Action1").GetRowCount
    For i=1 to countNum
    DataTable.GetSheet("Action1").SetCurrentRow(i) //使用SetCurrentRow(i)方法
    ―――ddd―――
    next
    13、while方法1,参数化时选择:dtLocalSheet
    Dim CountNum,i
    i=1
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    While i<=CountNum
    ------xuhuanti---
    DataTable.GetSheet("Action1").SetNextRow
    i = i+1
    Wend

    14、while方法2,参数化时选择:dtLocalSheet
    Dim CountNum,i
    i=1
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    While i<=CountNum

    DataTable.GetSheet("Action1").SetCurrentRow(i)
    ----xuhuanti---
    i = i+1
    Wend

  • HTML DOM学习心得(附:开心网查找空车位函数)

    Randall 发布于 2008-12-28 14:30:29

    HTML Dom是一个访问HTML文档的W3C标准。它定义了如何去访问页面元素对象以及属性和方法。
    在DOM标准里面:
    1 整个HTML文档是一个文档节点。
    2 每一个HTML 标签都是一个元素节点。
    3 HTML 文本都是文本节点。
    4 每一个HTML 属性都是一个属性节点。

    HTML DOM 的一些主要属性(x是一个HTEML元素)
    x.innerHtml - the inner text value of x (a HTML element)
    x.nodeName - the name of x
    x.nodeValue - the value of x
    x.parentNode - the parent node of x
    x.childNodes - the child nodes of x
    x.attributes - the attributes nodes of x

    HTML DOM 的一些主要方法(x是一个HTEML元素)
    x.getElementById(id) - get the element with a specified id
    x.getElementsByTagName(name) - get all elements with a specified tag name
    x.appendChild(node) - insert a child node to x
    x.removeChild(node) - remove a child node from x

    通常访问HTML DOM节点有一下三种方法:
    1 使用getElementById()
      node.getElementsByTagName("tagname");
    2 使用getElementsByTagName()
      x=document.getElementsByTagName("p");
      For i = 0 to x.Length - 1
        Print x(i).innerText
    3 使用HTML文档的节点树导航
      node.firstChild
      node.childNodes
      node.parentNode

    掌握HTML DOM对qtp web测试是很有帮助的。
    下面有个简单的例子,在开心网上搜索好友列表并把相应的车位状态取出来。如果用qtp实现的话有下面几个难点,好友的列表的长度是动态变化的,好友名称是不固定的,不同的登陆用户有不同的好友。
    使用HTML DOM就可以比较方便的解决找个问题,查看页面源代码我们知道每一个好友都是存在一个"UL"标签里面,而好友的车位状态是存在"LI"标签的子节点里面。

    Function Find_Park()
    Dim d
    Set d = createobject("scrīpting.dictionary")

    'Get all the "UL" tag from the page, each object contains the information of one friend
    Set friends = Browser("争车位 - 开心网").Page("争车位 - 开心网").Object.getElementsByTagName("ul")
    For i = 0 to friends.Length - 1
     'Get all the "LI" tag within each friend, one object  whose style is "FLOAT: right" contain the status of the park
     Set friendAttrs = friends(i).GetElementsByTagName("li")

     blnFlag = False
     For j = 0 to friendAttrs.Length - 1
      If strComp("FLOAT: right", friendAttrs(j).style.csstext, 1) = 0 Then
       Set imgs =  friendAttrs(j).GetElementsByTagName("img")
       d.Add friends(i).InnerText, imgs(0).GetAttribute("alt")
       blnFlag = True
       Exit For
      End If
     Next

     If Not blnFlag Then
      d.Add friends(i).InnerText, "空"
     End If
    Next

    Set Find_Park = d
    End Function

  • QTP测试flex制作的flash网站的方法

    ylian 发布于 2008-07-15 18:21:42

    现在Flex做的网站由于画面效果很好,现在很受欢迎,但是了解flash自动化测试的人寥寥无几,最近有项目是这方面的,研究了一番,略有成果,现总结如下:

    一.QTP自动化测试flex制作的flash系统需要插件, 插件安装方法如下:

    1. 到这个地方 https://www.adobe.com/cfusion/td ... us&product=flex 其在flex automation for QTP,需要注册,很快的。

    2.下载下的文件名为flexATWin.exe ,将后缀该为“.rar”文件

    3.解压缩flexATWin.rar文件

    4.检索“*.exe”文件

    5.你会看见一个“Flex2_Plugins_QuickTestPro.exe”文件,这是一个独立的文件有37.5MB大,将它可以单独拷贝出来,其他的文件可以删除,这个就是flex 的QTP插件了

    6.安装Flex2_Plugins_QuickTestPro.exe 文件,打开QTP9.2 发现


    7.OK,下面就靠大家研究如何适用flex了。

    二.仅仅安装好插件是不够的,还需要满足下面条件:

     环境:
    1.flex automation只能安装在QTP 9.1 及以上版本
    2.必须安装flex 2.0.1, 而且你的应用程序必须在flex 2.0.1下编译
    3.flex plugin for qtp 只支持 IE6及以上版本。
    4.必须安装flash player 9.0.28或以上版本
    5.JRE 1.4.2或以上版本


    三.确认是不是安装成功:


    1.检查注册表,如没发现有TEAPluginIE.dll和TEAPluginQTP.dll,则说明没有安装成功

    2.或者打开QTP==》tools==》object indentification==》Environment下拉框中是否有Flex2.0.1选项

      如果有表示安装成功。


    四.录制flex制作的flash系统,有些系统是不录制的。

    1.在系统编译的时候需要倒进来automation.swc, automation_agent.swc, and qtp.swc 这几个包文件文件,

    其中automation.swc默认就有,不需要重新导入

    automation_agent.swc, and qtp.swc 这两个是从你安装flex for qtp testing 插件的目录下面取出来的,有时候还需要automation_agent_rb.swc

    默认文件存放在C:\Program Files\Adobe\Flex Automation\frameworks下面的两个文件夹里面,将他们放到你系统对应的lib下面。

    如果你的系统用到了Flex的chart,那么还需要导入automation_charts.swc

    2.然后就是重新编译,发布,如果没有以外的话现在你的系统就可以使用QTP录制了。

    补足:如果自动化测试Flex系统,其实对flex系统还有其他方面的要求,详细请参考 官方说明


    现在,你基本上是一个flex自动化测试的高手了,前提是你对QTP有一定的了解。

  • QTP访问外部数据之一:数据库

    zhou840401 发布于 2008-07-10 20:52:49

       QTP有时候需要访问数据库,以下整理了一些访问数据库常用的FUNCTION

    '================================================
    '说明:连接数据库
    '参数:curSession,数据库连接的指针,用于后面具体访问的操作
    'connection_string,连接字符串,如 
    'connection_string="Provider=MSDAORA.1;Password=password;User ID=user;Data Source=orcl;Persist Security Info=True"
    '返回值:0表示连接数据库成功,其它的为出错信息。
    '================================================
    Function db_connect( byRef curSession ,connection_string)
        dim connection
        on error Resume next
        ' 打开连接
        set connection = CreateObject("ADODB.Connection")
        If Err.Number <> 0 then
            db_connect= "Error # " & CStr(Err.Number) & " " & Err.Descrīption
            err.clear
            Exit Function
        End If
     
        connection.Open connection_string
        If Err.Number <> 0 then
            db_connect= "Error # " & CStr(Err.Number) & " " & Err.Descrīption
            err.clear
            Exit Function
        End If
        set curSession=connection
        db_connect=0
    End Function

    '==============================================
    '说明:断开数据库连接
    '参数:curSession,数据库连接的指针
    '返回值:无
    '==============================================
    Function db_disconnect( byRef curSession )
        curSession.close
        set curSession = Nothing
    End Function


    '===============================================
    '说明:通过查询语句,得到一个记录集
    '参数:curSession,数据库连接的指针,SQL,相关SQL语句
    '返回值:函数返回一个记录集'
    '==============================================
    Function db_execute_query ( byRef curSession , SQL)
         set rs = curSession.Execute( SQL )
        set db_execute_query = rs
    End Function
    '=============================================
    '说明:获取记录集的行数
    '参数:curRS,记录集的指针
    '返回值:返回行数
    '===============================================
    Function db_get_rows_count( byRef curRS )
        On error resume next
        dim rows
        rows = 0
        curRS.MoveFirst
        Do Until curRS.EOF
            rows = rows+1
            curRS.MoveNext
        Loop
        db_get_rows_count = rows
    End Function

    '=============================================
    '说明:得到记录集当中某一行某一列的值
    '参数:curRecordSet,记录集的指针,rowIndex,行的标识,从0开始,
    'colIndex,列的标识,从0开始,可以是列名
    '============================================
    Function db_get_field_value( curRecordSet , rowIndex , colIndex )
        dim curRow
     
        curRecordSet.MoveFirst
        count_fields = curRecordSet.fields.count-1
        If ( TypeName(colIndex)<> "String" ) and ( count_fields < colIndex ) then
            db_get_field_value = -1 'requested field index more than exists in recordset
        Else
            curRecordSet.Move rowIndex
            db_get_field_value = curRecordSet.fields(colIndex).Value
        End If
    End Function

    补充说明:数据库连接字符串(连接数据库的时候用到的),可以通过新建一个后缀名为udl的文件,通过该文件完成数据库的连接之后,用文本的方式打开该文件,就可以得到数据库连接的字符串了。


  • 使用Object Repository Automation Objects and Methods操作对象库

    Randall 发布于 2008-07-13 11:39:58

    Dim RepositoryFrom,TOCollection
    Set RepositoryFrom = CreateObject("Mercury.ObjectRepositoryUtil")
    RepositoryFrom.Load "C:\Login.tsr"
    Set TOCollection = RepositoryFrom.GetAllObjectsByClass("WinButton")
    Msgbox TOCollection.Count

    具体可参照help文档中关于ObjectRepositoryUtil的应用.

    'The following example retrieves an object repository's objects and properties,

    'looks for specific test objects using several methods, and copies a test object
    'to another object repository.
    Dim ImageObj, PageObj, RepositoryFrom, RepositoryTo
    Set RepositoryFrom = CreateObject("Mercury.ObjectRepositoryUtil")
    Set RepositoryTo = CreateObject("Mercury.ObjectRepositoryUtil")
    RepositoryFrom.Load "C:\QuickTest\Tests\Flights.tsr"
    RepositoryTo.Load "E:\Temp\Tests\Default.tsr"


     

    Function EnumerateAllChildProperties(Root)
    'The following function recursively enumerates all the test objects directly under
    'a specified parent object. For each test object, a message box opens containing the
    'test object's name, properties, and property values.
        Dim TOCollection, TestObject, PropertiesCollection, Property, Msg
        Set TOCollection = RepositoryFrom.GetChildren(Root)
        For i = 0 To TOCollection.Count - 1
                Set TestObject = TOCollection.Item(i)
                Msg = RepositoryFrom.GetLogicalName(TestObject) & vbNewLine
                Set PropertiesCollection = TestObject.GetTOProperties()
                For n = 0 To PropertiesCollection.Count - 1
                    Set Property = PropertiesCollection.Item(n)
                    Msg = Msg & Property.Name & "-" & Property.Value & vbNewLine
                Next
                MsgBox Msg
    EnumerateAllChildProperties TestObject
        Next
    End Function


     

    Function EnumerateAllObjectsProperties(Root)
    'The following function enumerates all the test objects under a specified object.
    'For each test object, a message box opens containing the test object's name,
    'properties, and property values.
     Dim TOCollection, TestObject, PropertiesCollection, Property, Msg
        Set TOCollection = RepositoryFrom.GetAllObjects(Root)
        For i = 0 To TOCollection.Count - 1
            Set TestObject = TOCollection.Item(i)
                        Msg = RepositoryFrom.GetLogicalName(TestObject) & vbNewLine
                Set PropertiesCollection = TestObject.GetTOProperties()
                For n = 0 To PropertiesCollection.Count - 1
                    Set Property = PropertiesCollection.Item(n)
                    Msg = Property.Name & "-" & Property.Value & vbNewLine
                Next
            MsgBox Msg
        Next
    End Function


     

    Function RenameAllImages(Root)
    'The following function sets a new name for all image test objects under a specified object.
     Dim TOCollection, TestObject, PropertiesCollection, Property
        Set TOCollection = RepositoryTo.GetAllObjectsByClass("Image")
        For i = 0 To TOCollection.Count - 1
                Set TestObject = TOCollection.Item(i)
                RepositoryTo.RenameObject (TestObject, "Image " & i)
                RepositoryTo.UpdateObject TestObject
        Next
    End Function


     

    Function RemoveAllLinks(Root)
    'The following function recursively enumerates all the test objects under a specified object.
    'It looks for all test objects of class Link and removes them from their parent objects.
        Dim TOCollection, TestObject, PropertiesCollection, Property
        Set TOCollection = RepositoryFrom.GetChildren(Root)
        For i = 0 To TOCollection.Count - 1
                Set TestObject = TOCollection.Item(i)
                TOClass = TestObject.GetTOProperty("micclass")
             If TOClass = "Link" Then
                    RepositoryFrom.RemoveObject Root, TestObject
                End If
            EnumerateAllChildProperties TestObject
        Next
    End Function


     

    Call EnumerateAllChildProperties(Null)
    Call EnumerateAllObjectsProperties(Null)
    Call RenameAllImages(Null)
    Call RemoveAllLinks(Null)
    Set ImageObj = RepositoryFrom.GetObject("Browser(""CNN.com"").Page(""CNN.com"").Image(""Remains identified"")")
    If (Not IsNull(ImageObj)) Then
     MsgBox RepositoryFrom.GetLogicalName(ImageObj)
     Else MsgBox "null"
    End If
    Set PageObj = RepositoryTo.GetObjectByParent("Browser(""CNN.com"")", "Page(""CNN.com"")")
    If (Not IsNull(PageObj)) Then
     MsgBox RepositoryTo.GetLogicalName(PageObj)
     Else MsgBox "null"
    End If
    RepositoryTo.AddObject ImageObj, PageObj
    RepositoryFrom.Save
    RepositoryTo.Save
  • (转载) 修炼成QTP高手的十个步骤

    zte_boy 发布于 2008-07-09 21:54:19

    http://motevich.blogspot.com/上看到一篇文章,讲述成为QTP高手需要学习的几个方面的知识,以及一些有用的链接:
    1. VBscrīpt QTP实用VBscrīpt作为测试脚本语言,因此需要掌握很多VBscrīpt的知识:
    2. 软件测试自动化框架
    3. QTPTutorial帮助文档 Sources: '\help\QTTutorial.pdf' or '\help\Tutorial.chm' in QTP Install folder.
    4. QTP的用户指南 Sources: '\help\QTUsersGuide.pdf' or '\help\MainUsersGuide.chm' in QTP Install folder.
    5. COM/DCOM 技术 主要是Excel, Word, Outlook等相关的COM技术:
    6. SQL
    7. XML
    8. HTML, DOM 测试WEB应用程序时必须了解:
    9. HPQTP Knowledge Base 包含很多实用的QTP技术文章:
    10. 一些有用的网站
  • 在qtp中随机取下拉菜单的值

    qicyt1812 发布于 2008-02-25 15:46:15

    在QTP中随机取下拉菜单的值

    文章来源:中国IT实验室
    有网友在论坛上提出问题,在使用QTP中如何随机选取动态的下拉菜单。在此笔者总结了一些测试经验,利用51testing的登录界面(http://bbs.51testing.com/logging.php?action=login)作为测试页面进行讲解。
         首先我们拿登录页面中的  安全提问  这个下拉菜单作为测试对象。
               
       


    2.JPG


        我们可以先录制一段选取下拉菜单的脚本。
        Browser("51Testing软件测试论坛 测试 | 软件测试\").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").Select "您个人计算机的型号"。
        备注:无
       
        这边有个技术处理就是使用#加数字来选择我们的下拉菜单。
        Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").Select "#2"
        备注:这个方法在论坛上也出现过,比较适合这个例子。

        下面我们要取得下拉菜单中选项的个数。
        Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
        备注:这边使用GetROProperty,应该算比较常见的,所以不多做解释。

        接下来是要个随机函数,参考帮助。
    Randomize
    x=RandomNumber (0,2)
        备注:这边是随机生成0-2之间的三个数字中的一个。

        我们可以把随机函数写成function,方便以后使用。
    Function Get_Ran(i)
       Randomize
      Get_Ran=RandomNumber (0,i)
    End Function
        备注:这边需要注意的就是使用了函数返回值

        最后我们把脚本整合起来
    Function Get_Ran(i)
       Randomize
      Get_Ran=RandomNumber (0,i)
    End Function

    Get_Count=Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
    Ran_Number=Get_Ran(Get_Count-1)
    Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").Select "#"&Ran_NumberBrowser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
    Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
        备注:需要注意的就是在下拉菜单选择的时候从#0开始计算的,所以随机数字从0开始,传入的值也需要减去1。

        题外话:这边主要是使用QTP自带的随机数字函数这个方法来实现随机选择下拉菜单的内容,其实这个随机数字可以开展到随机字符串。因为我们经常会有一些输入域的测试,有的就需255个字节,多的就更可怕,使用随机函数能大大减少我们的工作量。而下面这个例子是实现在abc这三个字母中随机取出来拼成字符串。
    Function makestring(inputlength)
    If IsNumeric(inputlength) Then
    For I = 1 To inputlength
    'you may add a random function here
    A = Array("a","b","c")
    Randomize
    x=RandomNumber (0,2)
    B = A(x)
    makestring =makestring +B
    Next
    msgbox ("output the string:"&makestring )
    else
    msgbox ("error format:"&inputlength)
    End If
    End Function
    Call makestring("8")
  • qtp 文件读写

    hett 发布于 2008-07-07 14:32:33

    fileobject = fso.Getfile(path)

    TextSream = FileObject.OpenAsTextStream(mode,format)

    TextStream = FSO.CreateText.File(filename, bOverwrite)

    注意三个函数的返回值。

     

    例子一:

    Dim txtapp
    Dim  f

    Set txtapp =  CreateFile("d:/qtp.txt",true)   '返回TextSream.
    WriteToFile txtapp ,"this is the fist line"     '直接把txtapp放到WriteToFile里

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Function CreateFile(sFile, bOverwrite)

        Set fso = CreateObject("scrīpting.FileSystemObject")

        set CreateFile = fso.CreateTextFile(sFile, bOverwrite)   '返回TextSream.并且注意这个时候不能执行 CreateFile.close.否则后面就不能写入。(因为和后面写入的是同一个 TextStream .)
     

    End Function

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    function  WriteToFile(sFilename, sLine)
     
    Const ForWriting =2
    Set fso = CreateObject("scrīpting.FileSystemObject")

    sFilename.Write sLine

    sFilename.Close

    End function

    ***********************************************************************************

    ************************************************************************************

    例子2

    Dim txtapp

    Set txtapp =  CreateFile("d:/qtp.txt",true)   '返回TextSream.

    WriteToFile "d:/qtp.txt" ,"this is the fist line" '是把路径传给了 WriteToFile.

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Function CreateFile(sFile, bOverwrite)

        Set fso = CreateObject("scrīpting.FileSystemObject")

        set CreateFile = fso.CreateTextFile(sFile, bOverwrite)   '返回TextSream
      CreateFile.close                                    '注意 一定要关闭。否则下次打开的时候,就不能写入

    End Function

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    function  WriteToFile(sFilename, sLine)
    Dim getf
    Dim f
    Const ForWriting = 2
    Set fso = CreateObject("scrīpting.FileSystemObject")

    set  getf =fso. getfile(sFilename) '返回 file object ,这时进来的是 path

    Set f =getf.OpenAsTextStream( ForWriting,-2) '返回text sream

    f.Write sLine

    f.Close

    End function

     

     

     


     

     

     

     

     


     

  • 根据页面结构使用描述性编程读取页面中经常变动的内容 ---- 无需依赖对象-1

    qicyt1812 发布于 2008-07-09 11:43:28Top 1 Digest 1

    根据页面结构使用描述性编程读取网页中的链接 --- 无需依赖对象

    '在脚本中编写使用哪种浏览器开启哪个网页,这样更方便
    InvokeApplication "C:\Program Files\Internet Explorer\IEXPLORE.EXE http://www.google.cn/"
     
    '定义Browser对象
    Dim descBrowser
    Set descBrowser = Descrīption.Create()
    descBrowser("openurl").value="http://www.google.cn
    "

    '定义Page对象
    Dim descPage
    Set descPage = Descrīption.Create()
    descPage("url").value="http://www.google.cn
    "

    '定义Link对象,也就是要读取的链接
    Dim descLink
    Set descLink =  Descrīption.Create()
    descLink("html tag").value = "A"
     
    '找到包含该Link链接的的父对象DIV,然后通过父对象来获取符合条件的子孙数量(此处为:链接的数量),使用index属性循环读取这些链接即可
    For i=0 to 1
     set pd_link =  Browser(descBrowser).Page(descPage).WebElement("html tag:=DIV","Class:=left","index:="&i).ChildObjects(descLink)

     For j=0 to pd_link.count()-1
      Browser(descBrowser).Page(descPage).WebElement("html tag:=DIV","Class:=left","index:="&i).Link("index:="&j).click
      Browser(descBrowser).back
     Next

    Next

    '根据页面结构使用描述性编程读取网页中的链接 --- 无需依赖对象属性,只要知道页面的结构就可以轻松完成,非常方便实用,大家可以用FireFox中的Debug工具来查看页面属性。

  • QTP测试PDF的方法

    zte_boy 发布于 2008-07-09 22:09:41

    Adobe的PDF文件是目前通用的文件格式之一,很多文档都以这种格式来存储。在使用QTP进行自动化测试的过程中,经常要验证PDF文件的内容是否满足要求,因此需要访问PDF文件的内部属性。
     
    幸好Adobe提供了以COM方式访问PDF的接口,使得我们可以实现QTP测试PDF的自动化过程。下面是一个简单的例子,用于打开一份PDF文档,读取PDF文档的页数:
    Option Explicit
    Dim gApp, gPDDoc, jso
    Set gApp = CreateObject( "AcroExch.App" )
    Set gPDDoc = CreateObject( "AcroExch.PDDoc" )
    If gPDDoc.Open( "D:\Doc\AutomatedTesting.pdf" ) Then
    Msgbox gPDDoc.GetNumPages
    End If
    Set gPDDoc = Nothing : Set gApp = Nothing
  • (转)QTP中连接MySQL的方法

    lynmin 发布于 2008-07-15 20:15:46

    QTP中连接MySQL的方法(数据库验证点和ADO连接)

    2008-06-29 18:28:00 / 个人分类:原创文章

    很多朋友对于QTP中连接MYSQL束手无策,其实根本原因是默认的我们的操作系统中ODBC驱动里默认不支持开源的MySQL驱动。51Testing软件测试网sL)[ZK'p r} B
    要解决这个问题的方法非常简单,安装一个相关的驱动就能解决问题了。
    7pQf_-q0b Y]/N46301 这里给出这个驱动程序的下载地址: MyODBC-3.51.11-2-win.exe
    lL[a0o46301 安装完毕后,到“控制面板--管理工具--数据源ODBC--系统DSN”把它添加进来,步骤见下面截图qtpmysqsl1.JPG到qtpmysqsl5.JPG(我在本机上安装了一个Discuz论坛)。51Testing软件测试网(mM5{ a&\,x6b^
    添加完毕后,就可以开始使用了。
    4W#C%P-_o4ZO46301 以下给出具体的实现过程
    uVtWk5[-B#EYg46301 (一)数据库验证点:51Testing软件测试网L })I(O$b tW'k(x
    见下面截图 qtpmysqsl6.JPG 到 qtpmysqsl9.JPG
    P%^{d$r+V46301 (二)ADO连接MySQL数据库的代码:
    +D8[(Xrw_d7n,r46301 例子(获取论坛中的帖子主题和内容):

    CODE:

    Dim Cnn, Rst, strCnn51Testing软件测试网m+n ?!sP0^Tb
    51Testing软件测试网!B!Qt6gt@T G
    strCnn = "DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;DATABASE=discuz;USER=root;Option=3"
    $X v2Ko}(AE ^46301 Set Cnn = CreateObject("ADODB.connection")51Testing软件测试网 \.}~4Wa {
    Cnn.Open strCnn51Testing软件测试网C/OR dA(^%b\Wr
    Set Rst = CreateObject("ADODB.Recordset")
    |nz(G7h46301 Rst.Open "select * from cdb_posts", Cnn51Testing软件测试网;X7x/Re2~H
    Rst.MoveFirst
    8k)s'uYqtJ46301 While Rst.EOF <> True
    r(Un3T:Ys"O46301     MsgBox Rst.Fields("subject") & Chr(13) & Chr(10) & Rst.Fields("message") & Chr(13) & Chr(10)
    0Ip,w8q.\)e46301     Rst.MoveNext51Testing软件测试网8]B%P8z'l V
    Wend51Testing软件测试网1GY1N V3V v|
    Rst.Close51Testing软件测试网(x.wMjr(}
    Cnn.Close
    -T.N/j,m"Fq!^46301 51Testing软件测试网 ? H%\ @;Mf
    Set Rst = Nothing
    z5t/i-g&hg&WX46301 Set Cnn = Nothing
    51Testing软件测试网9s[:X&I H3nv;s N~
    51Testing软件测试网Ft-KHDF
    qtpmysqsl1.JPG51Testing软件测试网P4Q@q-w3~

    /y`E"\h2n6C(O46301qtpmysqsl2.JPG
    b*|;|Tob4630151Testing软件测试网"xj}_5S-z|`
    qtpmysqsl3.JPG
    %e"c6@{y&ERD?Y46301
    A:bJ$C3[:@~OK46301qtpmysqsl4.JPG51Testing软件测试网!^ Hbe#o)L F
    51Testing软件测试网8E o-\B\ fO.b K
    qtpmysqsl5.JPG51Testing软件测试网 ym_1k L2m Jgl

    wt} d*I@~%Y2H[46301qtpmysqsl6.JPG
    9dbe!Y}t5Z9^9c4630151Testing软件测试网7dSl#YB9X%s
    qtpmysqsl7.JPG51Testing软件测试网1a:y*Q9~9q*{
    51Testing软件测试网0f h7^5B6\x U3ubJ7d
    qtpmysqsl8.JPG51Testing软件测试网-o _4cw I)|)t8X
Open Toolbar