发布新日志

  • (转)QTP动作参数值传递

    2009-03-19 18:04:41

     关于QTP动作的参数,我做了四个动作,各自进行值传递。

            关键字视图如下:
        

            以Action2为例,设置属性如下:

        

            其代码为:

            

            Action2获得的值就是其它动作的输出值,此时获得Action1的输出值:

          

            直接修改Action2的动作调用参数,在Value选择值的来源。当你已经给Action1定义了输出值后,它将会在Value的列表中显示出来。


            这样,我就可以从Action1到Action4各定义输入值,然后输出给下一个动作。

            运行出来结果就是:

           

  • (转)QTP:FileSystemObject基础知识

    2009-03-19 17:57:43

      在QTP测试中,比较本地的两个文件是不是相同,需要使用VBScript的FileSystemObject对象,在此作简要的概述
    一.基础FileSystemObject
    1.     创建 FileSystemObject 对象
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")
      Scripting 是类型库的名字,而 FileSystemObject 则是想要创建的对象的名字。
      要用 FileSystemObject (FSO) 对象模式来编程,则:使用 CreateObject 方法来创建 FileSystemObject 对象。
      FSO 对象模式包含在 Scripting 类型库中,该库位于 Scrrun.dll 文件中。因而,要使用 FSO 对象模式,必须把 Scrrun.dll 放在 Web 服务器的适当系统目录中。
    2.     使用方法:
      访问现有驱动器、文件和文件夹
    GetDrive()、GetFolder()、GetFile()、CreateFolder()、CreateFile()、CreateTextFile ()、OpenTextFile()、FolderExists(url)、DeleteFolder(url)、MoveFolder(src,to)、FileExists(url)、CopyFile()、MoveFile()、DeleteFile()、
    例如:
    Dim fso, f1
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f1 = fso.GetFile("c:\test.txt")
    3.     访问属性:
    Name、Path、Size、Type、DateLastModified(上一次修改的文件时间)
    二.FSO的一些特殊功能
    1.        GetSpecialFolder Method 返回特定的Windows文件夹的路径:
      Windows安装目录;Windows系统目录;Windows临时目录
      FSO.GetSpecialFolder([0, 1, or 2]) 
    2.        GetTempName Method 返回一个随机产生的文件或者目录名字,用于存储临数据
    3.        GetAbsolutePathName Method 返回文件夹的绝对路径(类似于Server.MapPath)。
    比如,FSO.GetAbsolutePathName("region") 将返回类似于下面的结果:"c:mydocsmyfolder egion"
    4.        GetExtensionName Method 返回路径中最后部分的扩展名 (比如:FSO.GetExtensionName("c:docs est.txt") 将返回txt)
    5.        GetBaseName and GetParentFolder Methods 返回路径中最后部分的父文件夹 (比如:FSO.GetParentFolder ("c:docsmydocs") 将返回'docs')
    6.        Drives Property 返回所有本地可用驱动器的集合,用于建立资源浏览器样的用户接口。
  • (转)学习QTP后的总结

    2009-03-19 17:52:23

    1、拆分语句split
    例:取得当前日期后拆分
    riqi=date()
        my=split(riqi,"-")
        riqi=my(1)&"月"&my(2)&"日"
        datatable("riqi",DtGlobalSheet)=riqi
        本地表:DataTable("a", dtLocalSheet)
    riqi= year(date)& "-" & Right("0"& month(date),2) & "-"&Right("0"&   Day(Date),2)

    2、取得表格中某行某列的值GetCellData
    例:飞机票取票价
    shuA=Browser("Welcome: Mercury Tours").Page("Book a Flight: Mercury").WebTable("New York to Zurich").GetCellData(3,3)


    3、取距某年某月某日的天数datediff
    例:计算距2008-08-08奥运天数
    datediff("d",now,"2008-8-8")


    4、描述性编程text:=
    例:取得某页面上某文字的链接
    Browser("").Page("").Link("text:=娱乐").Click
         或
         neirong="娱乐"
         Browser("").Page("").Link("text:="&neirong).Click


    5、网页中HTML编辑器的录制
    功能:验证126邮箱的发信功能正确
    操作步骤:
          a.录制脚本,动作包括整个发信的过程。
          b.修改脚本,在输入信件主题代码后加wait 10语句
           c.回放脚本,观察在邮件正文中输入的内容,回放时QTP是否写入
          d.重新修改脚本,保证回放时QTP在邮件正文中写入内容

    英文解决方案:
        Browser("网易126免费邮--你的专业电子邮局").Page("网易电子邮箱 - xueqinzhaoqing@126.co").Frame("indexFrame").WebEdit("subject").Click
        wait 1
         Setting.WebPackage( "ReplayType")=2      '配置使用浏览器事件或鼠标运行鼠标操作的'方式.1 - 使用浏览器事件运行鼠标操作,2 - 使用鼠标运行鼠标操作。
         Set ōbj=createobject("wscrīpt.shell")
         obj.sendkeys "{TAB}"
         wait 2
         obj.sendkeys "abc1111"
         wait 1
         Setting.WebPackage( "ReplayType")=1
    中文解决方案

    strCopy = "软件测试." 
    Set ōbjIE = CreateObject("InternetExplorer.Application") 
    objIE.Navigate("about:blank") 
    objIE.document.parentwindow.clipboardData.SetData "text", strCopy 
    objIE.Quit

    wait 1
    Setting.WebPackage( "ReplayType")=2
    Set ōbj=createobject("wscrīpt.shell")
    obj.sendkeys "{TAB}"
    wait 2
    obj.sendkeys "^v"
    wait 1
    Setting.WebPackage( "ReplayType")=1

    6.使用Multi Test Manager添加文件时可以直接往里拖的哦。

    7.函数:新建记事本,改名为public.vbs例:
       function ZHIRSS
    ZHIRSS="RSS行业资讯分类维护"
    end function
      使用语句executefile "d:\zhaopin\case\denglu.vbs"或设置QTP test/settings/resources/+函数目录

    8.设置动作循环:右击/actiong call properties/run on all rows

    9.设置动作允许被调用:右击/action properties/general/reusable action打勾

    10.QTP与MTM连接:Tools/option/run/allow other mercury products to run...

    11.插入已存在的动作1)insert/call to copy of action...复制可修改
                       2)insert/call to existing of action...复制不可修改

    12.QTP报告自动跳出设置:Options>Run>View results when run session ends

    13.判断表格是否存在:
    If Browser("数商3.0后台管理系统").Page("Page").Frame("main_5").WebTable("标题").Exist then
    reporter.ReportEvent 0,"pass","系统显示了所有的资讯列表!"
    else
      reporter.ReportEvent 1,"fail","系统没有显示资讯列表!"
    end if

    14.获取表格行数:Browser("数商3.0后台管理系统").Page("Page").Frame("main_5").WebTable("标题").RowCount

    15.注释脚本存在位置:qtp/dat/ActionTemplate.mst

    16取本地文件名称Function ShowFileList(folderspec)
       Dim fso, f, f1, fc, s
       Set fso = CreateObject("scrīpting.FileSystemObject")
       Set f = fso.GetFolder(folderspec)
       Set fc = f.Files
       For Each f1 in fc
          s = s & f1.name
          s = s &   "  "
       Next
       ShowFileList = s
    End Function
    wenjian=ShowFileList("D:\下载\本地下载1\")

    17.取本地文件删除:del= DeleFile("D:\下载\本地下载1\")
    Function DeleFile(folderspec)
       Dim fso, f, f1, fc, s
       Set fso = CreateObject("scrīpting.FileSystemObject")
       Set f = fso.GetFolder(folderspec)
       Set fc = f.Files
       For Each f1 in fc
             f1.delete
       Next
    End Function

    18.sousuo2=Browser("Browser").Page("Page_4").Check (CheckPoint("2007-11-08 14:21"))
    If (sousuo2)eqv(true) Then
        reporter.ReportEvent 0,"",""
    else
       reporter.ReportEvent 1,"",""
    End If

    19.取参数化数据的行数,只在某几行进执行某些语句
    row=datatable.GetSheet(3).getcurrentrow
    If row = 3 Or row = 4 Then

    20.单选框置灰zhihui=Browser("下载中心--新增下载文件").Page("下载中心--新增下载文件_4").WebRadioGroup("downloadType").GetROProperty("disabled")
    If  zhihui=1 Then
    End If

    29.取树结构
    Set Desc=descrīption.create
    Desc("micclass").value="WebTable"
    Set List=Browser("Browser").Page("Page").Frame("main").ChildObjects(Desc)
    yuqi=List(0).GetROProperty("innertext")
    msgbox yuqi
    yuqi=split(yuqi," ")
    msgbox yuqi(1)

    30.关闭所有IE
    SystemUtil.CloseProcessByName("iexplore.exe")

    31.创建action template.
        当希望在每一个新建action时都增加一些头部说明,比如作者、创建日期、说明等,用action template
        来实现最简单快捷。
        方法:用记事本等文本编辑器,输入如下类似的内容:
              'Company: xxxx
              'Author: xxx
              'Product: xxx
              'Date: xx
             然后将文件保存为ActionTemplate.mst,并存放到QTP安装目录下的dat目录。

    32.启动IE的语句:SystemUtil.Run "iexplore.exe", "http://www.***.com"
       关闭IE或其他程序的语句:SystemUtil.CloseProcessByName "app.exe"
         or  SystemUtil.CloseProcessByWndTitle "Some Title"

    33.获取图片的名称
    ObjectName = Browser(…).Page(…).Image("Find").GetProperty("Name")

    34.检查某个对象是否存在,如果存在弹出对话框说明对象存在。
    If Browser("Browser").Page("Page").Applet("login.html").JavaEdit("username").Exist Then
    MsgBox("The object exists.")
    End if

    35.同步点
    Browser("数商3.0制作平台").Dialog("Microsoft Internet Explorer").WaitProperty "visible", True, 120000
    设置test/test settings/object synchronizationg timeout 一致

    36.视图框显示为乱码时:调整原页面编码,在QTP/tools/change active screen

    37.添加附件:
       Browser("**").Page("**").WebFile("filePath").Click
    Browser("**").Dialog("**").WinEdit("文件名(N):").Set "D:\**.jpg"
    Browser("下载中心--新增下载文件").Dialog("选择文件").WinButton("打开(O)").Click
    添加相应的对象


    38.在图片上右击添加:tools/web event recording configuration/custom settings
    webedit/event/add/onblur,onchange,onfocus,onpropertychan,onsubmit
    webdlement/event/add/onclick,onmousedown,onmouseup/listen always

    39.数据执行保护
      方法一、右击我的电脑/高级/性能/设置/数据执行保护/为除下列选定程序之外的所有程序和服务启用DEP/添加被保护的程序。
      方法二、C:/BOOT.INT修改noexecute=alwaysoff

    40.在图片上右击添加:tools/web event recording configuration/custom settings
    webedit/event/add/onblur,onchange,onfocus,onpropertychan,onsubmit
    webdlement/event/add/onclick,onmousedown,onmouseup/listen always

    41.去掉前后空格
    If trim(mingcheng)=trim(yuqi) Then

    42.分类树问题解决
    Set Desc=descrīption.create
    Desc("micclass").value="WebTable"
    Set List=Browser("Browser").Page("Page").Frame("main").ChildObjects(Desc)
    yuqi=List(0).GetROProperty("innertext")
    msgbox yuqi
    yuqi=split(yuqi," ")
    msgbox yuqi(1)


    43.引用自定义环境变量
    Environment.LoadFromFile "D:\询价\case\环境\huiyuan.xml"

    44.环境变量有2种,一种是QTP的内置变量,一种是用户自定义的变量。内置变量是可以直接就可以用,自定义环境变量需要在菜单中选择“文件”——>“设置”——>“环境”,在变量类型中选择“用户自定义”,然后进行添加,可以对添加的变量全部导出,导出的文件为.xml格式的文档。既然可以导出,那么必然可以导入.xml文件,你可以在该对话框中的选中“从外部文件导入”,然后添加其文件路径即可。(当然这些操作都可以直接使用脚本来实现,如:Environment.LoadFromFile(“FileName”))
    例如:在桌面建立一个Var.xml,如下
    -<Environment>    //以这个开始的内部都是定义环境变量,直到以</Environment>结束
    - <Variable>                           // 变量定义起始标识
                     <Name>aa</Name>               // 变量名称
                     <Value>11</Value>               // 变量值
            </Variable>                            // 变量定义结束标识
    - <Variable>
                     <Name>bb</Name>
                     <Value>22</Value>
            </Variable>
    - <Variable>
                     <Name>cc</Name>
                     <Value>33</Value>
                  </Variable>
      </Environment>
    然后导入本测试的环境变量文件中,在专家视图里编写下面的脚本代码:
    Dim aParam3
    aParam3=Environment.Value(“aa”)          // 调用环境变量
    msgbox aParam3
    运行测试,会输出”11”

    45.在HTML编辑器中写入数据
    用低水平录制写入编辑器过程,增加编辑部器前的对象,加入click事件,再用TAB
    例如:
    Browser("广告管理").Page("广告管理").WebEdit("descrīption").Click
    Window("Microsoft Internet Explorer").WinObject("Internet Explorer_Server").Type mictab
    Window("Microsoft Internet Explorer").WinObject("Internet Explorer_Server").Type "aaa"

    46.Browser("creationtime:=1").close
       两个页面title相同无法识别时使用描述必编辑
        Browser("creationtime:=1").page(title:=****).WebEdit("name:=***").Set "***"
        或Browser("creationtime:=1").page(index:=1).WebEdit("index:=0").Set "***"

    47.场景恢复:
       当某些提示框会在不定期时有提示时,如果自动点击确定或某些按钮
       1、tools/recovery scenaril manager,制作相应的提示框和要点击的按钮,并保存
       2、test/settings/recovery,添加刚保存的.qrs

    48.输入验证码,先提示一个输入框,在输入框内输入验证码,点击[确定],把输入的验证码框
       Dim a
      a = InputBox("输入名字")

    49.对象库中对象名称不分为_2,_3...设置:tool/options/web/page/fram options/
         crate a new page test object for为different test object descrīptons
         crest a new frame. test object for为different test object descrīptions

    50.验证测试输入框输入的最大允许字数功能的正确

    QTP脚本代码中编写
    Set aa=Browser("Browser").Page("Page").Frame("main").WebEdit("PayTypeName")
    if konglen(aa,20) eqv true then
    reporter.ReportEvent 0,"添加支付方式,支付方式输入框允许输入的最大字符功能正确",""
    else
    reporter.ReportEvent 1,"添加支付方式,支付方式输入框允许输入的最大字符功能错误",""
    end if

    此函数的功能为:验证测试输入框输入的最大允许字数功能的正确,函数可写在public.vbs中
    Function konglen(duixiang,guifanshu)
    duixiang.Click
    wait 1
    Setting.WebPackage( "ReplayType")=2
    Set ōbj=createobject("wscrīpt.shell")
    i=0
    ōld="a"
    xin="b"
    while old<>xin
    ōld=duixiang.GetROProperty("value")
    i=i+1
    wait 0,20
    obj.sendkeys "1"
    wait 0,20
    xin=duixiang.GetROProperty("value")
    wend
    'msgbox i
    If i-1=guifanshu Then
    konglen=true
    else
    konglen=false
    End If
         Setting.WebPackage( "ReplayType")=1
    End Function

    51.超时设置:Setting("DefaultTimeout") =1000000

    52.共享对象库:Set App = CreateObject("QuickTest.Application")
    App.Test.Settings.Resources.ObjectRepositoryPath = "path"

    53.取颜色   browser("b").page("p").Object.currentStyle“:.color
    54.显示行号设置:Tools- --> Editor Options...-->General-->Show line number,


    55.不同数据库检查点手动SQL写法
    QTP插入数据库检查点,手动指定SQL语句的写法。
    一、SQL Server格式(本地无需安装SQL Server)
    connectionstring(连接字符串):
    1.本地没有创建数据源的方式
    DRIVER=SQL Server;SERVER=数据库IP地址;UID=用户名;PWD=密码;APP=Microsoft Office 2003;WSID=本地主机名;DATABASE=数据库名

    实例:
    DRIVER=SQL Server;SERVER=10.160.11.10;UID=sa;PWD=sa;APP=Microsoft Office 2003;WSID=RJHLJUN;DATABASE=dcwork

    2.本地已创建数据源的方式
    DSN=数据源名称;UID=用户名;PWD=密码;APP=Microsoft Office 2003;WSID=数据库的主机名;DATABASE=数据库名

    实例:
    DSN=LocalServer;UID=sa;PWD=sa;APP=Microsoft Office 2003;WSID=RJDCWORKTEST;DATABASE=dcwork

    3.SQL语句实例(从数据库表HR_LANGUAGE_TYPE中,查询字段语言名称LANGUAGE_NAME,条件语言名称=中文,按语言名称升序排序结果)
    source(SQL语句):
    SELECT HR_LANGUAGE_TYPE.LANGUAGE_NAME  FROM dcwork.dbo.HR_LANGUAGE_TYPE HR_LANGUAGE_TYPE  WHERE (HR_LANGUAGE_TYPE.LANGUAGE_NAME='中文')  ORDER BY HR_LANGUAGE_TYPE.LANGUAGE_NAME


    二、DB2格式:(本地至少安装DB2 Run-Time Client Lite)
    connectionstring(连接字符串):
    1.本地没有创建数据源的方式
    DRIVER={IBM DB2 ODBC DRIVER};UID=用户名;PWD=密码;MODE=SHARE;DBALIAS=数据库名;

    实例:
    DRIVER={IBM DB2 ODBC DRIVER};UID=db2admin;PWD=db2admin;MODE=SHARE;DBALIAS=DCWORK;

    2.本地已创建数据源的方式
    DSN=数据源名称;UID=用户名;PWD=密码;MODE=SHARE;DBALIAS=DCWORK;

    实例:
    DSN=DWCORKDB2;UID=db2admin;PWD=db2admin;MODE=SHARE;DBALIAS=DCWORK;

    3.SQL语句实例
    source:SQL语句
    SELECT HR_LANGUAGE_TYPE.LANGUAGE_NAME  FROM DB2ADMIN.HR_LANGUAGE_TYPE HR_LANGUAGE_TYPE  WHERE (HR_LANGUAGE_TYPE.LANGUAGE_NAME='中文')  ORDER BY HR_LANGUAGE_TYPE.LANGUAGE_NAME


    三、Oracle格式:(本地需要安装Oracle ODBC DRIVER)
    connectionstring(连接字符串):
    1.本地没有创建数据源的方式
    DRIVER={Oracle in OraHome92};SERVER=数据库服务名;UID=用户名;PWD=密码;DBQ=数据库名;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;

    实例:
    DRIVER={Oracle in OraHome92};SERVER=DCWORK;UID=DCWORK;PWD=DCWORK;DBQ=DCWORK;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;



    2.本地已创建数据源的方式
    DSN=数据源名称;UID=用户名;PWD=密码;DBQ=数据库名;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=F;BAM=IfAllSuccessful;MTS=F;MDI=F;CSR=F;FWC=F;PFC=10;TLO=0;

    实例:
    DSN=dcworkoracle;UID=DCWORK;DBQ=DCWORK;DBA=W;APA=T;EXC=F;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=F;BAM=IfAllSuccessful;MTS=F;MDI=F;CSR=F;FWC=F;PFC=10;TLO=0;

    3.SQL语句实例
    source:SQL语句
    SELECT HR_LANGUAGE_TYPE.LANGUAGE_NAME  FROM DCWORK.HR_LANGUAGE_TYPE HR_LANGUAGE_TYPE  WHERE (HR_LANGUAGE_TYPE.LANGUAGE_NAME='中文')  ORDER BY HR_LANGUAGE_TYPE.LANGUAGE_NAME



    四, mysql
    Set Conn = CreateObject("ADODB.Connection" )
    str="DRIVER={MySQL ODBC 3.51 Driver};SERVER=192.168.1.100;DATABASE=wp_blog;user id=zzz ; password=123456"
    Conn.open str
    Set Rs = CreateObject ("ADODB.Recordset" )
    sql = "select * from `wp_blog`.`blg_webcategory` limit 0, 5000;"
    Rs.open sql,conn,1,3
    If (not Rs.eof) then
    Rs.MoveFirst
    MsgBox Rs(0)
    MsgBox Rs(1)
    MsgBox Rs(2)
    MsgBox Rs(3)
    end if

    Rs.close
    Set Rs = Nothing
    Conn.close
    Set Conn = Nothing
    (转载于 http://bbs.51testing.com/thread-42921-1-1.html )

    五. access

    Set Conn = CreateObject("ADODB.Connection" )
    str="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:/db1.mdb"
    Conn.open str
    Set Rs = CreateObject ("ADODB.Recordset" )


    56.*.xml
    Environment.LoadFromFile "D:\新建文件夹\a.xml"
    Browser("百度一下,你就知道").Page("百度一下,你就知道").WebEdit("wd").Set Environment("HuiYuanB")

    57、类似时间控件,不能手到输入的文本档
       1)手工添加对象,
       2).object.value="2008-4-12"

  • (转)QTP测试报表table内容的思路

    2009-03-19 17:39:26

    使用QTP对报表中的webtable内容进行正确性验证。

        基本思路是:

        一:使用getcelldata(i,j)的方法遍历webtable把表格内容存入一个数组中,一般为二维数组

        二:使用数据库连接组件ADODB连接后台数据库,使用数据结果集对象保存select查询结果,也是一个二维数组

        三:此时区分是否需要验证排列顺序,如果需要,直接对两个二维数组进行一对一遍历比较

        四:不需要验证排列顺序,或者顺序无法控制的情况下,我们需要对显示内容和查询预期内容进行比较,这时候牵涉到两个结果集的数据顺序问题,如果采用单对多遍历的情况,效率会十分低。

        这时候我们换一种思路考虑,既然是验证内容,那我们就可以把二维数组的验证转换成排序一维数组比较,实现方式是,采用join方法将二维数组的每一行转换成一个字符串(内容没有变化,只加入拼接符),两个二维数组进行相同转换,成为两个一维的字符串数组。

        然后使用快速排序法对两个一维数组进行一次排序,同样的机制下,如果原本内容相同,那么排序出的内容也应该相同。然后直接进行一维数组一对一比较。

        下面是vbs的快速排序代码,合适数字和字符串数组:

    Public Function QSort(ByRef ReArr, ByVal head, ByVal tail)

    'ReArr 是待排序数组, head和tail是该数组的最小下标和最大下标
    Dim lef, rig
    Dim pivot

    If head < tail Then
     lef=head
     rig=tail
     pivot=ReArr(lef)
     While (lef <> rig)

      While (lef < rig and ReArr(rig) >= pivot)
       rig = rig-1
      Wend
      If lef <rig Then
       ReArr(lef) = ReArr(rig)
       lef = lef+1
      End If

      While (lef < rig and ReArr(lef) <= pivot)
          lef = lef+1
      Wend
      If lef <rig Then
       ReArr(rig) = ReArr(lef)
          rig = rig-1
      End If
     
     Wend

     ReArr(lef) = pivot
     call QSort(ReArr, head, lef-1)
     call QSort(ReArr, lef+1, tail)
     
    End If
    End Function

  • (转)对象库管理和编写脚本

    2009-03-19 17:14:00

    使用QTP录制一些脚本再回放,这不难,难的是一个测试团队共同开发脚本,并能不断的完善脚本,创建一个结构化的自动测试脚本体系。这篇文章重点讨论的是,如何管理QTP的对象仓库,以便能让对象仓库易于维护、管理。51Testing软件测试网} Y1m3Y3[NtB
      如果只是简单的录制、回放脚本,可能感觉不到对象仓库的存在。但是要做到QTP脚本的结构化管理,就必须对QTP的对象仓库进行严格的管理。51Testing软件测试网+F[ Q!t:A#[Y
    51Testing软件测试网:?F!s!nV-CN
      在实际工作中我们发现,QTP脚本做好后绝不是一成不变的,而是随着需求和页面的变化,需要不断修改的。如果每次修改脚本的时候,都重新录制脚本,成本极高,所以最有效的方法是,先修改对象仓库,然后修改脚本,以适应新的系统。51Testing软件测试网 jQU.zvf
    51Testing软件测试网 UW2}*t%ts
      如果对象仓库里的管理比较混乱的话,修改脚本时就会遭受地狱般的痛苦,比如n多对象全堆在一起根本理不出头绪,对象的命名不知所云,找不到自己需要的对象等等。下面我们讲一下如何管理对象仓库,避免这些问题。51Testing软件测试网"I1{|!Q^;Y6]y

    HL*c YT-]g$Z&X138711先介绍一下对象仓库中的对象层次,主要分为3个层次51Testing软件测试网b~`0K!b5f"r
    1、Browser浏览器51Testing软件测试网n`7T0Jnn Np*f
    2、Page页面51Testing软件测试网9cHE%nO.oe
    3、页面中的各种对象,比如Link、Button
    _k i jq3jf m13871151Testing软件测试网 _di L}$@
      Browser对应的是已经打开的IE窗口对象,Page对应的是不同的网页,比如登录首页是一个Page,登录成功后跳转到我的淘宝页面,这就是另一个Page。而页面中的各种对象就比较好理解了,图片、按钮、链接都是对象。
    [#xB {3Ha;n7t13871151Testing软件测试网r$jr _4|g
      了解了对象层次,我们再讲一下命名。如果QTP在录制过程中自动记录对象,命名是非常乱的,缺乏逻辑性,经常看到一个Browser下面有n多“淘宝网_1”、“淘宝网_2”这样的Page,这对我们以后的管理非常不利。与其修改这些命名,我们不如用一种思路更清晰的方式,手动添加对象。51Testing软件测试网(`$z H'n+C_KM

    !Q S.]i+|.{e)m3^ P138711  QTP中有一个工具实现了对象仓库的管理,Object Repository Manager,我们用它来添加对象。操作很简单,直接点击toolbar中的Add Object按钮,然后在web上点击你需要添加的对象即可,添加过后再修改名称。更新对象也比较简单,先选中需要更新的对象,然后点击Update from Application即可。
    6r [9a[C]+z%H,q138711
    .[(~/aAf138711  这项工作其实可以在系统页面出来以后就开始做,我们一边进行手工测试,一边把对象添加起来,为后面的脚本开发做准备。这时暂时不制作脚本。51Testing软件测试网B*a([)JA6l
    51Testing软件测试网)`:L atd&BuO|XH
      总结一下,对象仓库的管理要满足以下几个原则:51Testing软件测试网 g^3\)iA!kq
    1、每个Browser下的Page不要太多,最好不要超过5个,即使我们的系统都在同一个IE窗口下(没有弹出新IE),我们也可以分几个Browser管理,把业务上关联较强的几个Page放在一个Browser下;51Testing软件测试网5n7FD \ E m'w^
    2、每个对象都按照所代表的业务属性命名,最好用中文,不要出现一些难理解的字符,比如abc这样的。
    ,][a1Hs;SD1387113、尽量避免在一个tsr文件中堆放过多的对象,最好根据业务,把对象分为几个tsr文件保存。这里没有统一标准,以每个tsr文件结构清晰为宜。51Testing软件测试网"L;A-pJm3\.X}!V

    (N%m1Z(V.h.u138711  现在我们完成了对象仓库的整理,好,可以开始制作脚本了。可是问题来了,录制脚本的时候,QTP能不能自动和这些对象对应上呢?QTP会不会又自动添加一堆对象进来呢?别担心,不会出现这个问题,因为我们将进行一场脚本编写的革命:放弃“录制脚本”这种传统的脚本编写方法,完全手工编写脚本Gj'}%v-\6gF*P_+w138711

    ? D;kc~ces138711我们有了一套结构清楚的对象仓库以后,我们就可以轻松的手工编写QTP脚本了。
    E?S6@$rRepZd138711
    +~ _.TGv3e'IO$\j138711  这里可能有人会问,QTP的录制功能不是很强大么,为什么还要自己手写脚本,这样是不是更麻烦。我先说一下我对手写测试脚本的感受,供大家参考。首先,如果我们整理好对象仓库,再录制脚本,QTP就会又自动生成一批新的对象,命名很乱,再修改替换太费事;其次,录制脚本的过程如果出现问题,再重来,很麻烦;最后,也是最重要的,手写脚本时思路非常清楚,而且写完再运行,感觉非常好,呵呵。
    A0nDT2t X(dzS13871151Testing软件测试网a+uB0oOm@ T#r
      与编写脚本相比,脚本的维护工作同样很重要,而且维护脚本一般都是直接修改脚本,并不会去重新录制,所以开始的时候就用手写的方式,维护起来就会更轻松。
    *z"{vN5L*c-S138711
    U$~$M!XF5XoU138711  编写QTP脚本其实是比较简单、快速的。我们首先创建一个Test,然后把所有相关对象仓库的tsr文件和vbs文件添加到这个Test里面,下面就可以开始写了。写脚本大致会遇到这么几种情况:
    IP1X9a {yc.i1387111、调用vbs函数
    ~ `3TiwR1387112、调用其他Test51Testing软件测试网A&^#l_e
    3、打开指定的URL
    s"HnWU1387114、操作页面Page上的控件51Testing软件测试网z M m fi%Y
    5、添加CheckPoint51Testing软件测试网a&RaE um4kCkW
    6、其他逻辑运算51Testing软件测试网`1~O:LG*iEF
    51Testing软件测试网 o1G/?M1}hA @
      我们分别讲一下。调用vbs函数比较简单,直接Call [函数名]。如果要调用其他的Test,那么首先点击Call to Existing Test,然后在QC中选择一个可以复用的Test,例如登录。如果登录的Test有参数,那么可以这样写:51Testing软件测试网']1To4E2Z
    RunAction "Action1 [login]", oneIteration , "张三"
    2` c5Lf q`138711
    ,C7{*{ m/x*u1r6?138711  下面的脚本要操作对象仓库了。我们先写出“Browser(”,这时就会发现,对象仓库里面的Browser对象都列了出来,然后我们选择需要的那个B对象就好。我们先从打开指定URL的脚本开始讲,打开指定的URL使用的机会比较多,特别是在Test的开始。一般我们这样写51Testing软件测试网;RI2o`!O6ELR
    Browser("登录").Navigate "指定的URL"
    )if6`I#JJ138711
    J0Z,Fz+s138711  这里的“登录”是一个Browser对象,一般我们要选业务上符合的B对象。写完这句以后要再写:51Testing软件测试网0\"^ X4Z9z.W%d[2C
    Browser("登录").Page("登录首页").Sync
    }X*B?,?2@138711
    Kg(`d)UW? V138711  这句的意思是等待“登录首页”这个Page加载完毕,注意不要用Wait几秒这种方式来等待页面加载结束。51Testing软件测试网ww,LED/} i
    51Testing软件测试网;g5S5f{/U Tq:th
      操作Page的对象是比较简单的,由于控件的类型太多,比如下拉菜单WebList、文本输入框WebEdit、按钮WebButton,这里就不一一说明了,大家看下面的一些例子吧:
    a$m|0Wl U138711Browser("购买直充").Page("购买直充").WebList("游戏区").Select 151Testing软件测试网7\.re0O(B8d6h:Q
    Browser("购买直充").Page("购买直充").WebEdit("PlayerName").Set "abc"
    1J4d:`QC T ~138711Browser("购买直充").Page("购买直充").WebEdit("PlayerNameAgain").Set "abc"51Testing软件测试网'J1XHv"? T C5VR
    Browser("购买直充").Page("购买直充").WebEdit("CheckCode").Set "8888"
    )?sWFx1N!@138711Browser("购买直充").Page("购买直充").Image("Submit").Click
    L(D1v7J ]s/r13871151Testing软件测试网ia9m ]F!Y$H"q
      如果遇到问题,不知道怎么写,可以先用录制的方式,生成一些脚本,然后仿照脚本写就可以了。另外在Page下面有可能会有Frame对象,这个没关系,就像这样写即可:
    X c1L0D3Z/OKv1H$RfU138711Browser("我的直充").Page("我的直充").Frame("直充入口").Image("立即直充").Click
    dk)B[d[/^;^,ks I138711
    .Il Y`u r/p.H!O/~.O138711  添加CheckPoint要稍微复杂一些,比如说我们要检查Page上的一个WebElement的显示字符是否正确,那么首选要把这个WebElement完整的写在Test里面,这一句后面需要删除:51Testing软件测试网 qs3vq0k;k1v
    Browser("购买直充").Page("购买直充").WebElement("购买结果").Click51Testing软件测试网D/X&B5n]_B$x

    b9V}&{0C138711  然后右击这一行脚本,选择Insert Standard CheckPoint,在弹出的CP属性窗口,设置CP的细节。确认后脚本就会自动生成一行:51Testing软件测试网a*^2WeP8L#Z l
    Browser("购买直充").Page("购买直充").WebElement("购买结果").Check CheckPoint("购买结果")
    P4[ ID${7Q J!vO(o2S13871151Testing软件测试网9C_3H%O6S~#qc%S3\S
      最后再把上面那一行删除就可以了。51Testing软件测试网}4k;P;c(T v6LdV

    U?f| Wj+U138711  其他的逻辑运算,例如循环、判断,请参考vbs脚本语法,这里不说了。51Testing软件测试网$k"x:_'BZr*u

    p!k.A/Xh%Y$L5_138711  总之,手动编写QTP脚本有很多好处,我在尝试了录制和手写两种方式之后,最终选择了手写的方式,大家不妨也试试,特别是对编码有兴趣的朋友

  • (转)QTP资料整理

    2009-03-19 16:40:17

      QTP调用外部api

      '例1:运行一个exe文件

      Extern.WinExec "d:\1.exe ", 1

      '例2:Beep

       '它让我的机器在办公室里狂响不止!

      Extern.Declare micLong, "Beep", "kernel32.dll", "Beep", micLong

      Extern.Beep 500

      QTP 获取对话框中的信息

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

      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)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

      QTP获取对象属性名称用法:

      GetRoProperty----从应用程序界面上获取对象属性(即,是脚本运行时,获取的对象动态属性值)

      例如:获取对象库中index属性值,似乎只能用GetToProperty,因为应用程序界面上对象没有该属性,只是QTP为识别该对象创立的描述属性;

      GetToproperty----从对象库中描述对象的属性,静态值

      GetToProperties----获取用于标识对象的属性集;对于这个集合,有count等属性方法

      QTP在执行过程中往excel中写入值

      DataTable.GlobalSheet.AddParameter "Name", "liuxuedong"

      取datatable特定行的数据可以这样使用

      DataTable.GetSheet("Action1").GetParameter("test\").ValueByRow(1)
  • (转)QTP-使用技巧

    2009-03-19 16:01:56

    1.runaction后面能不能接变量(动态调用action,所以从数据库取数据做action名字了,但是调用总是找不到)? 

     A:脚本中原有RunAction "testbase [case1]", oneIteration

       把引号中的内容放到Global表中的第22行,然后将代码修改为:

       datatable.getsheet("Global")

       datatable.setcurrentrow(22)

     

       strLogin=DataTable("ActionName","Global")

       RunAction strLogin, oneIteration

      

       help中也有相关帮助

       :

       Syntax

       RunAction ActionName, [IterationMode , IterationRange , Parameters]

       ActionName : String : The name of the action

     

     

     

    2.QTP8.2中调用VB函数的问题(VBscrīpt写了一些测试脚本需要的几个通用函数,有没有办法可以用类似include的方式进行调用,而不需要每次都把这些函数Copy到新的脚本中)?

     A:程序开头加上ExecuteFile "..\..\..\project\DeVariable.vbs"

     

     

     

    3.QTP如何做回归测试(300多个TestCaseTD是否可以管理)

     A:TD可以实现,可以生成测试集,一个测试集可以包含若干个测试脚本

       QTP8.2本身提供一个工具Test Batch Runner但是运行完没有报告。

       MI有另一个工具叫MTMmultitestmanager

     

     

     

    5.QTP中如何设置使用别的浏览器(XP系统,用IE访问程序时,每次总提示屏蔽安装ActiveX插件,需要手动安装.但把这个过程录制到QTP后,回放一次是成功的。当我给某个输入框参数化了好多数据后,回放过程中,某些就会失败.

       可能有两个方面可以解决这问题1、每个动作设置延迟时间2、设置为用别的浏览器。)

       (失败的提示信息是 object not visible)

     A:1.延迟可用WAIT XX单位是秒)

       2.可以安装插件添加新的浏览器

          SystemUtil.Run "file” "params" "dir" "op'' "mode"

          QTP运行可执行文件的方法及其参数

        ps:建议是用IE浏览器,或者IE内核浏览器做测试

     

     

     

    6.checkpoint检查网页,是否能实现只要网页出现乱码就返回错误报告?

     A:Text not displayed能解决问题

       关于Text Checkpoint的总结。

       1Text Checkpoint的检查部分分为三个部分。Checked TextText BeforeText After。在默认的情况下,Checked Text执行的是精确检查,其余两个部分执行的是模糊检查。Text Before(After)检查的内容可以比实际的内容少。但是不能有和是实际内容不相符的地方,否则就失败。

       2) Exact match选项。如果选择了这个选项,三部分完全都进行精确检查。个人觉得和只检查checked Text部分没有区别。

       3) Text not displayed。这个选项本质上就是一个结果取反的过程。就是把检查的结果给反过来,pass变成FailFail变成pass。我觉得这样就很容易理解。

     

     

     

    7.WSH的应用方法

     A:WSH实际上是一个脚本语言的运行环境,它之所以具备强大的功能,是在于其充分挖掘了脚本语言的潜力。因此,如果抛开脚本语言而空谈WSH,那实际上就没有了意义。而如果再展开来讲述脚本语言,显然就离开了今天的主题。

     

    在这种情况下,只好采取一种折衷的方法:给大家推荐几个脚本文件利用WSH执行任务的实例,希望大家能通过这些例子对WSH的使用有一个初步的认识。

     

      脚本文件的编写十分方便,你可以选用任意一个文字编辑软件进行编写,编写完成后,只需将它保存为WSH所支持的文件名就可以了(如.js文件和.vbs文件)。最常用的就是记事本编辑器,下面的实例都是以它作为工具编写的。

     

    打开记事本编辑器,在上面编写如下内容:

      Wscrīpt.Echo("走近WSH")

      将它保存为以.vbs.js为后缀名(千万不要写成了.txt)的文件并退出记事本。双击执行这个文件。

      这一次,我们要利用WSH完成一次创建十个文件夹的工作。代码如下:

      dim objdir

      setōbjdir=wscrīpt.createobject("scrīpting.filesystemobject")

      for k=1 to 10

      anewfolder="c:\chapter" & k

      objdir.createfolder(anewfolder)

      next

     

    同样,将它存为.vbs文件并退出。运行后,我们会发现,C盘根目录下一次性多出了十个新文件夹。

     

       最后,再举一个在服务器上的运用。下面的代码将帮助你重新启动指定的IIS服务:  ' define a constant for stopped services

      Const ADS_SERVICE_STOPPED = 1

     

    ' get an ADSI object for a computer

      SetōbjComputer = GetObject("WinNT://MYCOMPUTER,computer")

     

    ' get an object for a service

      SetōbjService = objComputer.GetObject("Service","MYSERVICE")

     

    ' check to see if the service is stopped

      If (objService.Status = ADS_SERVICE_STOPPED) Then

     

    ' if the service is stopped, then start it

      objService.Start

     

      End If

     

    将它以startsvc.vbs为名保存在C:盘根目录。并通过如下命令执行:Cscrīpt C:\STARTSVC.VBS。运行后,经你指定的IIS服务项将被重新开启。

     

    其实,在Windowssamples目录下,有个WSH文件夹,那里面有不少很具代表性的.vbs. js脚本文件。

     

    此外,利用WSH还可以自己编写脚本文件来提高网络管理方面的效率。

     

     

    8.EXCEL中导出数据进行测试

     

    datatable.AddSheet("51sheet")

    datatable.ImportSheet "f:\test.xls","testsheet","51sheet"

     

    Dim i,RowCount '定义两个变量

    i=0

    RowCount=datatable.GetSheet("51sheet").GetRowCount '设置RowCount等于51sheet中的行数。

    msgbox RowCount

    Do while i<rowcount

    i=i+1 '第一次进入循环,执行这句后,i=1

    'datatable.getsheet("51sheet").setcurrentrow(i)  这句话被我注释掉了,正确的写法应该是下面这样,分开写。

     

    datatable.getsheet("51sheet")

    datatable.setcurrentrow(i)

     

    '执行过上面两句后,CurrentRow是第一行。

     

    tempData=DataTable.GetSheet("51sheet").GetParameter("Name").Value

                     

    '现在,我们调用msgbox看看下面这种调用方法得到的是什么值?没错,是第一行的值,下一次循环呢?

    '得到的是第二行的值么?

    msgbox "GetParameter-Name:"&tempData '这里弹出我们要看的值。

    '下面我们用另外一种方法来得到。

    msgbox "GetParameter-i:"&DataTable.GetSheet("51sheet").GetParameter(1).Value '这里我用GetParameter(1)去得到sheet中第一列的值。

    loop

     

     

     

    9.关于dtGlobalsheetdtLocalsheet

     

    1) dtGlobalsheet只有一个,它的index值比较特殊,它有两个index值,一个是1还有一个是内置的默认的1000

    你可以用1或者1000去引用它都是正确的。当然了,如果你用dtGlobalsheet来引用它也是正确的。这个sheetName叫做"Global"。注意:SheetName是区分大小写的。

    2) dtLocalsheet可以用index:1001来引用,当然,也可以用2来引用。至于其它自定义的sheet嘛,你就只能用index:3来引用了。

    它没有内置的默认的类似前两个那样的index值。

    3) datatable这个对象只有一个。就是所有sheet的集合。或许你把它理解为excel文件比较好。

    dtsheet呢?就是其中的每个sheet。所不同的就是MI为他们做了一些默认值。在我们的应用中,可能会有多个action,如:actiion1,actiion2,actiion3

    这些action也分别对应有各自默认的LoaclSheet.即:actiion1actiion2actiion3

     

    如果每个action中,我们都只用到一个sheet,那就好办了,在每个action中都可以用localsheet来引用,但是如果我们有两个及两个以上的sheet.那么就比较容易乱套了。

     

     

     

    10.移动当前位置的行

     

    For i=1 to 3

    datatable.getsheet("Global")

    datatable.setcurrentrow(i)

    DataTable("C","Global") = DataTable("nodename","Global")‘把表Global中的nodename字段中的内容取出来。

    Next

     

     

     

    11.如何能记录到页面的校验码?(Output value能不能得到web页面的校验码,一般的校验码是由图片随即生成的,用QTP怎么录脚本在登陆前得到校验码并输入到校验码一栏)

      A:1)一个很简单的方法:测试时叫开发屏蔽掉检验码的功能后,再录制脚本。检验码的功能可以手工很简单测试出来。

        2)想得到图片的校验码,唯一的方法就是跟程序员拿程序,然后自己在脚本里面写FUCNTION!

           其它就要手动输入了!

     

     

     

    13.自动测试实施计划

      1)分析实施自动化测试可能存在的风险:就是决定是否实施,用成本时间效果。。

      2)制定实施的时机:也就是在什么阶段

      3)研究所要测试的功能性能

      4)分析在测试中可能遇到的问题和困难

      5)预估所需要的人时和相应的硬件

      7)确定负责人员和相关测试人员

      6)制定详细的测试计划方案

      7)最后是执行计划

     

     

     

    14.一个Action里如何调用在另一个Action中定义的函数、过程(或变量、常量)

      例如:

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

      'Action_A

        Public strURL   

           ...... ......

       Function QueryList()

           ...... ......

           ...... ...... 

       End Function

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

      'Action_B

      '如何调用QueryList函数和strURL

      A1)可以把这些变量和Function放在vbs文件作为resource文件共享,在每个Action中添加该文件.         

     

    如果function中出现控件调用,那么必须确保该控件在相应的Actionobject repository中是存在的.

       2)定义一个可被调用的ACTION里面唯一的放一个FUNCTION

     

     

     

    15.如何管理QTP的源代码?(QTP生成的源代码比较多,而且和环境控件都有关,假如需要多人同时开发,请问如何管理源代码?)

      A:一个是代码你可以通过vss,cvs等来进行管理

        一个是通过td或者qc的基于用例的代码管理     

     

    其实第一种方法是基于版本控制来进行的,第二种方法是基于用例管理进行的

        角度不同,管理方法也不同,不过团队协作需要的大家分工明确,进度控制。代码管理可以借鉴开发的方法。

     

     

     

    16:脚本不能回放,IE中的AtiveX设置有问题??

      A: TOOL---OPTIONS----Ative screen

        然后点开advanced..,LOAD ACTIVEX CONTROLS打勾

        TOOL---OPTIONS----Ative screen

        然后点开advanced..,run scrīpts-->disabled!

     

     

     

    17.如何参数化link

     

    Browser("Browser").Page("Page").Sync

    Browser("Browser").Navigate "http://www.51testing.com/cgi-bin/index.php"

    Browser("Browser").Page("51Testing软件测试论坛---软件测试,软件质量工程师").Sync

     

    Set tags=Browser("Browser").Page("51Testing软件测试论坛---软件测试,软件质量工程师").Object.links

    Dim i,j, arr()

    i=0

    For Each element in tags

       If Ucase(element.tagname)="A" and left(element.InnerText,1)="[" Then

                           ReDim Preserve arr(i+1)

                       arr(i)=element.InnerText

       i=i+1

           end if

    Next

     

     

     

    For j=0 to i

                           Browser("Browser").Page("51Testing软件测试论坛---软件测试,软件质量工程师").Link("[版主讨论区]").SetTOProperty "Text",arr(j)

               Browser("Browser").Page("51Testing软件测试论坛---软件测试,软件质量工程师").Link("[版主讨论区]").Click

                           Browser("Browser").Back

    Next

     

    这段代码先是打开一个空的页面,然后输入url.

    到达论坛首页。

     

    然后得到所有版面的名称,也就是link的名称。

    存到数组里面。

    然后使用SetTOProperty更换录制时候录下的link的属性。

    这时候再click

     

     

    18. QTPDebug状态,Export View区域不能写入任何东西

     

    A:如果你的目的是在debug过程中修改已执行过的命令,可以在Debug viewCommand中执行命令,如重新执行已经执行过的命令,修改变量的值等等。

     

    如:Window("Flight Reservation").WinEdit("Name:").Set "51testing"

    已经执行,如果现在想修改“51testing”为“testing”,可以在command中执行

    Window("Flight Reservation").WinEdit("Name:").Set "testing"

     

     

     

    19动态变化值如何获取

     

    A:VAL=Browser("欢迎使用我的工作台").Page("欢迎使用我的工作台").Frame("managePlace_7").WebRadioGroup("userAccountId_0").GetROProperty("Value")

    Browser("欢迎使用我的工作台").Page("欢迎使用我的工作台").Frame("managePlace_7").WebRadioGroup("userAccountId_0").select val

     

     

     

    20.如何一一获得Table某栏linktext?

     

    A:通过上面link学习.我终于融会贯通,完成了我的问题:与大家共享:

     

     

    //////////////////////////////////////////////////////////////////////////////////////

    Browser("Login").Page("Page").Frame("contents").ViewLink("treeview").Image("Tplus").Click

    Browser("Login").Page("Page").Frame("contents").ViewLink("treeview").Image("Tplus_2").Click

    Browser("Login").Page("Page").Frame("contents").ViewLink("treeview").Link("开课设置").Click

    Browser("Login").Page("Page").Frame("main").WebList("drpStatus").Select "任意"

    Browser("Login").Page("Page").Frame("main").WebButton("查找").Click

    Browser("Login").Page("Page").Sync

     

    Dim finded,findCode,Nowout

    'define a constrat for find

    findCode = 110901  

    finded = false

     

    Function MaxPage(pageString)

      'msgbox pageString

      Dim ilen,i,j

      ilen = len(pageString)

      i=ilen

      While i>0

           j = mid(pageString,i,1)

              'msgbox j

              If instr("123456789",j)>0 Then

              MaxPage = j

                      'msgbox MaxPage

                      Exit function

              End If

              i=i-1

      Wend

    End Function

     

     

    Dim trowcount,maxp

    trowcount = Browser("Login").Page("Page").Frame("main_8").WebTable("开课代码").RowCount

    msgbox "Rowcount: "&trowcount

    Nowout = Browser("Login").Page("Page").Frame("main_8").WebTable("开课代码").GetCellData(trowcount,1)

    Nowout = trim(Nowout)

    maxp = MaxPage(Nowout)

    msgbox "max page: "& maxp

     

    Dim nowPage,checkid

    For nowPage = 1 to maxp

      If finded Then

              Exit for

      End If

     ' link to the当前所需page

     If nowpage>1 Then

       Browser("Login").Page("Page").Frame("main_8").Link("[2]").SetTOProperty "Text","["&nowpage&"]"

       Browser("Login").Page("Page").Frame("main_8").Link("[2]").Click

       Browser("Login").Page("Page").Sync

      end if

     

     ' Get the rowcount of table in now page

      trowcount = Browser("Login").Page("Page").Frame("main_8").WebTable("开课代码").RowCount

      msgbox "Rowcount: "&trowcount

     

     'link every record in the table of the page

      for i = 2 to trowcount - 2

           Nowout = Browser

  • (转)QTP模拟鼠标和键盘事件整理

    2009-03-19 15:57:37

      1、鼠标事件

      1.1 使用自带的Click方法

      看QTP的帮助,每个对象都有自带的Click方法,通过其中第三个参数指定具体的鼠标事件

      例如:

      Browser("New Page").page("New Page").WebElement("html tag:=Form").Click

      0,0,micRightBtn

      注意Click方法的前两个参数是相对坐标,即相对于对象控件左上角的坐标。

      然而执行脚本时常常发现右键功能无法回放。这需要通过设置回放级别解决。例如:

      Setting.WebPackage("ReplayType") = 2

      Browser("New Page").page("New Page").WebElement("html tag:=Form").Click

      0,0,micRightBtn

      Setting.WebPackage("ReplayType") = 1

      1.2 使用自带的FireEvent方法

      具体使用参考QTP的帮助吧,需要提醒一下,右键菜单的弹出对应的是"oncontextmenu"事件,这个帮助里没有提到,当然依赖于开发的代码实现。

      1.3 使用mercury.devicereplay

      Set devReplay = CreateObject("mercury.devicereplay")

      devReplay.MouseClick absx+4,absy+4,2

      1.4 使用Windows底层的mouse_event

      如果上面的方法仍然不管用,就要采用更底层的方法了。不过这种方式不推荐,因为mouse_event识别的是绝对坐标,你还需要在调用 mouse_event前获取对象的绝对坐标。需要说明的是,如果没有使用MOUSEEVENTF_ABSOLUTE,函数默认的是相对于鼠标当前位置的点,用0,0表示,会被认为是当前鼠标所在的点。

      Extern.Declare micVoid, "mouse_event", "user32.dll", "mouse_event", micByte,micByte,micDWord,micULong

      Extern.mouse_event MOUSEEVENTF_RIGHTDOWN,0,0,0

      2、键盘事件

      2.1 SendKeys

      最常用的模拟键盘操作的事件就是SendKeys了,具体说明一样参考QTP的帮助。

      需要说明的是QTP帮助中的例子,需要做一些调整,QTP中执行不需要显示指定Wscrīpt执行shell命令,否则会报错。正确的例子如下:

      Set WshShell = CreateObject("Wscrīpt.Shell")

      WshShell.sendKeys "{DOWN}"

      2.2 Mercury.DeviceReplay

      Set devReplay = CreateObject("mercury.devicereplay")

      devReplay.SendString("a")

      下面这篇文章介绍的比较清楚。

      http://www.51testing.com/?161787/action_viewspace_itemid_84200.html

      2.3 使用Windows底层的keybd_event

      Extern.Declare micVoid, "keybd_event", "user32.dll", "keybd_event", micByte,micByte,micDWord,micULong

      Extern.keybd_event 42,0,0,0

      注意一下这里的第一个参数是10进制的。

      SendKeys的使用要方便一点,但是稳定性不如后者,

      Function RtClick( Obj )

      absx = Obj.GetROProperty("abs_x")

      absy = Obj.GetROProperty("abs_y")

      Set devReplay = CreateObject("mercury.devicereplay")

      devReplay.MouseClick absx+4,absy+4,2

      set devReplay = nothing

      End Function
  • (转)QTP自动化测试工程师需要掌握的DOM

    2009-03-19 15:49:54

    在使用QTP测试WEB页面时,经常需要利用测试对象中的Object属性来访问和操作DOM,因此,QTP自动化测试工程师非常有必要掌握一些常用的DOM知识。 下面就列举了一些常用的DOM属性、方法和集合:

      常用DOM 属性

      ●  className.同一样式规则的元素用相同的类名。可以通过className快速过滤出一组类似的元素。

      ●  document.用于指向包含当前元素的文档对象。

      ●  id.当前元素的标识。如果文档中包含多个相同id的元素,则返回一个数组。

      ●  innerHTML.用于指向当前元素的开始标记和结束标记之间的所有文本和HTML标签。

      ●  innerText.用于指向当前元素的开始标记和结束标记之间的所有文本和HTML标签。

      ●  offsetHeight, offsetWidth.元素的高度和宽度。

      ●  offsetLeft, offsetTop.当前元素相同对于父亲元素的左边位置和顶部位置。

      ●  outerHTML.当前元素的开始标记和结束标记之间的所有文本和HTML标签。

      ●  outerText.当前元素的开始标记和结束标记之间的所有文本,但不包括HTML标签。

      ●  parentElement.当前元素的父亲元素。

      ●  sourceIndex.元素在document.all集合中的索引(index)。

      ●  style.元素的样式表单属性。

      ●  tagName.当前元素的标签名。

      ●  title.在IE中,代表元素的tool tip文本。

      常用DOM 方法

      ●  click().模拟用户对当前元素的鼠标点击。

      ●  contains(element).用于判断当前元素是否包含指定的元素。

      ●  getAttribute(attributeName, caseSensitive).返回当前元素所包含的某个属性,参数attributeName为属性名、caseSensitive表示是否大小写敏感。

      ●  setAttribute(attributeName, value, caseSenstive). 设置当前元素的属性。

      常用DOM 集合

      ●  All[].当前元素中包含的所有HTML元素的数组。

      ●  children[].当前元素包含的孩子元素。

  • (转)QTP中调用带有参数的Action

    2009-03-16 17:24:38

    调用带有参数的操作

            如果所调用的操作已定义了输入和/或输出参数,您还可以提供输入参数的值以及输出参数的存储位置,作为 RunAction 语句的参数。输入参数列在输出参数之前。

            对于输入参数,可以指定一个固定值,也可以指定另一个已定义的参数(数据表参数、环境参数或调用操作的操作输入参数)的名称,输入参数将采用该已定义参数的值。

            对于输出参数,可以指定一个用于存储值的变量,或者是一个已定义参数(数据表参数、环境参数或调用操作的操作输出参数)的名称。

            带有参数的操作调用使用以下语法:

            RunAction ActionName,IterationQuantity,Parameters

            例如,假设从 Action1 调用 Action2,并且 Action2 有一个已定义的输入参数和一个已定义的输出参数。

            RunAction "Action2", oneIteration, "MyValue", MyVariable

            为输入参数提供 MyValue 的字符串值,并将输出参数生成的值存储在名为 MyVariable 的变量中。

            RunAction "Action2", oneIteration, Parameter(ìAxn1_In), DataTable("Column1_out", dtLocalSheet)

            使用为 Action1 的 Axn1_In 输入操作参数定义的值作为该输入参数的值,并将输出参数生成的值存储在 Action1 的数据表工作表中名为 Column1_out 的一列中。

  • (转)通过Action参数来传递数据

    2009-03-14 18:03:50

    Action2的脚本如下:
    ' Input Parameters
    Message = Parameter("Msg")
    Msgbox Message
     
    ' Output Parameters
    If NOT Message = "" Then
           Parameter("ReturnMsg") = "The Message is " & Message
    Else
           Parameter("ReturnMsg") = "The Message is Empty!"
    End If
     
    ' RetuenValue
    ExitAction "HAHAHAHHAHA!!!!!"
    'ExitAction Parameter("ReturnMsg")
     
     
    3种调用Action的方法,Action1的脚本如下:
    ' 调用Action2,输入参数为 “ Hello!”,把输出参数值写到ReturnMessage1变量
    RunAction "Action2", oneIteration,"Hello!" ,ReturnMessage1
    Msgbox ReturnMessage1
     
    ' 调用Action2,输入参数为 “ Hello!”,通过Parameter方法读取输出参数值
    RunAction "Action2", oneIteration,"Hello!"
    ReturnMessage2= Parameter("Action2","ReturnMsg")
    Msgbox ReturnMessage2
     
    ' 如果被调用的Action使用了ExitAction来退出Action并返回ReturnValue,则可以使用下面的方式来获取Return Value的值
    ' 注意OutPut Parameters与Return Value的区别
    ReturnMessage3 = RunAction( "Action2", oneIteration ,"Hello!")
    Msgbox ReturnMessage3
     
    通过全局数据表(Global Data Table)来共享数据
     
     
    在Action1中设置参数值,Action1的脚本如下:
    ' 获取全局数据表
    Set Sheet = DataTable.GetSheet("Global")
    ' 查找参数列
    Set Parameter1 = Sheet.GetParameter("Column1")
    Set Parameter2 = Sheet.GetParameter("Column2")
    ' 设置参数值
    Parameter1.Value="Hello"
    Parameter2.Value="World!"
    ' 调用Action2,Action2将使用前面设置的参数值
    RunAction "Action2", oneIteration
     
    在Action2中读取参数值,Action2的脚本如下:
    ' 获取全局数据表
    Set Sheet = DataTable.GetSheet("Global")
    ' 读取参数值
    Set Parameter1 = Sheet.GetParameter("Column1")
    Set Parameter2 = Sheet.GetParameter("Column2")
    ' 使用参数值
    Msgbox Parameter1 &" " & Parameter2
     
    使用环境变量(Environment Variables)来共享数据
     
     
    在Action1中使用环境变量中定义的LoginUserName和LoginPassWord,Action1的脚本如下:
    ' 在Action1中使用环境变量中定义的LoginUserName和LoginPassWord
    UserName = Environment.Value("LoginUserName")
    UserPassWord = Environment.Value("LoginPassWord")
     
    SystemUtil.Run "C:\Program Files\Mercury Interactive\QuickTest Professional\samples\flight\app\flight4a.exe"
    Dialog("Login").Activate
    Dialog("Login").WinEdit("Agent Name:").Set UserName
    Dialog("Login").WinEdit("Password:").SetSecure UserPassWord
    Dialog("Login").WinButton("OK").Click
     
    ' 调用Action2,在Action2中也将使用到定义的环境变量
    RunAction "Action2", oneIteration
     
    在Action2中使用环境变量中定义的LoginUserName,Action2的脚本如下:
    ' 在Action2中使用环境变量中定义的LoginUserName
    UserName = Environment.Value("LoginUserName")
     
    Window("Flight Reservation").Activate
    Window("Flight Reservation").WinObject("Date of Flight:").Click 1,6
    Window("Flight Reservation").WinObject("Date of Flight:").Type "121212"
    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").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:").Set UserName
     
     
    通过Dictionary对象来在Action之间共享数据
    (1)添加注册表
    HKEY_CURRENT_USER\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects\GlobalDictionary
     
    ProgID = "Scripting.Dictionary"
     
     
    (2)使用GlobalDictionary对象
    ' 使用GlobalDictionary前清空里面的数据
    If GlobalDictionary.Count > 0 Then
           GlobalDictionary.RemoveAll
    End If
    ' 存储一个数值
    DepartDate = "2008-3-31"
    GlobalDictionary.Add "DateCheck", DepartDate
     
    ' 可在当前Action使用GlobalDictionary中的数据,也可在另外一个Action中使用添加到GlobalDictionary的数据
    'Dim CompareDate
    'CompareDate=GlobalDictionary("DateCheck")
    'Msgbox CompareDate
     
     
    ' 可在当前Action使用GlobalDictionary中的数据,也可在另外一个Action中使用添加到GlobalDictionary的数据
    Dim CompareDate
    ' 读取GlobalDictionary中的DateCheck数据
    CompareDate=GlobalDictionary("DateCheck")
    Msgbox CompareDate
     
  • (转)在QTP中如何运用XML管理参数

    2009-03-05 10:48:51

    我们现阶段是运用XML文件,存放页面输入操作数据
    优点:树型结构,可读性较好;操作简便
    缺点:如数据庞大,不便维护;以文件形式管理数据,效率太低

    另外也可以运用EXCLE维护数据
    优点:操作简便
    缺点:可读性差;维护效率低

    或者连接数据库,以数据库形式管理(这点LR支持的比较好,提供了连接功能接口,操作简便,而我用的QTP8.2支持不大好),总的来说,以数据库形式管理参数数据,其优势是其他两种数据管理方式无法取代的
    优点:对于参数数据量很大的情况下,便于管理
    缺点:平时要维护数据库,增加工作量

    2)实现方法与规范:
    QTP的“Test settings”->"Environment"中,提供了环境变量设置的功能。我们可以运用此接口,在外部文件的形式存储与管理对象库和参数,其中我们把对象集中放在名为Object Repository的文件夹中,对象文件的后缀名均为TSR。参数文件均放在名为XML的文件夹中,参数文件的后缀名均为XML。

    实现步骤:a、设置环境变量:
                    “Test settings”->"Environment"
                    b、Variable type:User-defined
                    c、Click “New”
                    d、input “name”、“Value”
                    (such as->name:XMLPath_1)
                    e、save
                    f、QTP脚本中写语句读取环境变量:
                    ( Such as->XMLPath=Environment.Value("XMLPath_1") )
                    g、用VB写函数,用于检索XML中的关键字,提取参数值
                    (见如下代码),VB函数可以写在后缀名为VBS的文件中
                    h、在QTP中加载VB函数:
                      “Test settings”->"Resources"
                      在"Associated library files"中加载VBS函数文件
                      点击“Set as Default”

    注:1)这里的Value我们可以输入XML的存放地址,用于把文件地址传到QTP脚本中

  • (转)ByVal和ByRef的区别

    2009-03-02 10:03:33

    ByVal 传送参数内存的一个拷贝给被调用者。也就是说,栈中压入的直接就是所传的值。
    ByRef 传送参数内存的实际地址给被调用者。也就是说,栈中压入的是实际内容的地址。被调用者可以直接更改该地址中的内容。

    ByVal 可选的。表示该参数按值传递。
    ByRef 表示该参数按地址传递。 ByRef 是 Visual Basic 的缺省选项。

    ByVal是传递值 源数据不会被修改
    你可以把这个值当作自己的局部变量来使用
    ByRef是传递地址 , 源数据可能被修改
    你对这个变量的操作将对你传入的那个变量产生影响,就像指针的感觉

    实例:
    sub Add1(ByVal no as int32)
        no=no+100
    end sub
    sub Add2(ByRef no as int32)
        no=no+100
    end sub
    private sub button1_click(sender as object,e as eventargs)handles button1.click
        dim a as int32
        a=100
        Add1(a)
        msgbox (\"a的值为:\" & a)     '显示:a的值为100
        Add2(a)
        msgbox (\"a的值为:\" & a)     '显示:a的值为200,因为Add2中的参数no为ByRef,即
                                     '按地址传递,因此在Add2中对no进行修改后,将会导致
                                     '源参数a的值也被修改。
    End Sub

    ——————————————————————————————————————
    3、ByVal和ByRef
        ByVal传递的参数值,而ByRef传递的参数的地址。在这里,我们不用去区别传指针/传地址/传引用的不同,在VB里,它们根本就是一个东西的三种不同说法,即使VB的文档里也有地方在混用这些术语(但在C++里的确要区分指针和引用)
        初次接触上面的程序二SwapPtr的朋友,一定要搞清在里面的CopyMemory调用中,在什么地方要加ByVal,什么地方不加(不加ByVal就是使用VB缺省的ByRef)
        准确的理解传值和传地址(指针)的区别,是在VB里正确使用指针的基础。
        现在一个最简单的实验来看这个问题,如下面的程序三:
    【程序三】:'体会ByVal和ByRef
        Sub TestCopyMemory()
            Dim k As Long
            k = 5
    Note:   CopyMemory ByVal VarPtr(k), 40000, 4
            Debug.Print k
        End Sub

        上面标号Note处的语句的目的,是将k赋值为40000,等同于语句k=40000,你可以在"立即"窗口试验一下,会发现k的值的确成了40000。
        实际上上面这个语句,翻译成白话:
    -----------------------------------------------------------------
    就是从保存常数40000的临时变量处拷贝4个字节到变量k所在的内存中。
    -----------------------------------------------------------------
        现在我们来改变一个Note处的语句,若改成下面的语句:
    Note2:   CopyMemory ByVal VarPtr(k), ByVal 40000, 4
        这句话的意思就成了,从地址40000拷贝4个字节到变量k所在的内存中。由于地址40000所在的内存我们无权访问,操作系统会给我们一个Access Violation内存越权访问错误,告诉我们"试图读取位置0x00009c40处内存时出错,该内存不能为'Read'"。
        我们再改成如下的语句看看。
    Note3:   CopyMemory VarPtr(k), 40000, 4
        这句话的意思就成了,从保存常数40000的临时变量处拷贝4个字节到到保存变量k所在内存地址值的临时变量处。这不会出出内存越权访问错误,但k的值并没有变。
        我们可以把程序改改以更清楚的休现这种区别,如下面的程序四:
    【程序四】:'看看我们的东西被拷贝到哪儿去了
        Sub TestCopyMemory()
            Dim I As Long, k As Long
            k = 5
            I = VarPtr(k)
    NOTE4:  CopyMemory I, 40000, 4
            Debug.Print k
            Debug.Print I
            I = VarPtr(k)
    NOTE5:  CopyMemory ByVal I, 40000, 4
            Debug.Print k
        End Sub

    程序输出:
    5
    40000
    40000
        由于NOTE4处使用缺省的ByRef,传递的是i的地址(也就是指向i的指针),所以常量40000拷贝到了变量i里,因此i的值成了40000,而k的值却没有变化。但是,在NOTE4前有:i=VarPtr(k),本意是要把i本身做为一个指针来使用。这时,我们必须如NOTE5那样用ByVal来传递指针i,由于i是指向变量k的指针,所以最后常量40000被拷贝了变量k里。

    引用
    ByVal vs ByRef
    The difference between ByVal and ByRef is very simple once we recall the subject on pointers. These keywords are simply abbreviations of the full definition of the differences between the two.

    ByVal = By Value and ByRef = By Reference

    Now we can recall what I said in the previous chapter about C/C++ and pointers. Pointers act as a Reference to a memory address location. In VB however, this means that the reference is occurring in your statement directly at the location of the actual data, and where it is stored.

    Selecting a ByVal would thereby mean you are only working on a copy or replica of the data, and not the actual data segment it self.

    This has specific implications for how your statements can handle and alter the data in your variable. The ByRef use, would imply that a change performed by the statement of the value you pass, has an affect on the actual data, while the ByVal use would only alter the copy the statement has to work on.

    Simply described, if passed ByRef, a procedure can permanently alter the data stored in the variable. Since it also is faster to send a memory address location, rather than passing a copy of a data argument, it is the default value used by Visual Basic.

    ByVal和ByRef的区别
  • QTP 常用的函数

    2009-02-26 15:53:41

    1.GetCellData函数

      作用:获取单元格的值

      例: 

     rowCount = Browser("xxx ").Page("xxx ").Frame("xxx").WebTable("xxx").RowCount
    For counter = 1 To rowCount
      text = Browser("xxx").Page("xxx").Frame("xxx").WebTable("xxx").GetCellData(counter,1)
      If (text = "xxx") Then
        counter = counter - 1
        selectNO = "#" & counter
        Browser("xxx").Page("xxx").Frame("xxx").WebRadioGroup("xxx").Select selectNO
        Exit For
      End If
    Next

      2.把值插入datatable里

      例:

          datatable.setcurrentrow(i)
            datatable.value("name","Global")="name"
            datatable.value("passwd","Global")="passwd"

      3.用代码来启动浏览器

       Browser1 = "IE"
      StartURL = "www.51testing.com"
      IF Browser1 = "IE" THEN
         set IE = CreateObject("InternetExplorer.Application")
         IE.Visible = true
         IE.Navigate StartURL
      END IF

      4.ExecuteFile函数

      作用:ExecuteFile 可以直接执行vbs文件,而不需要将其导入resource中
            ExecuteFile FileName
      说明: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
         strtext1 = "xxx"
         strtext2 = "xxx"
         str = VbWindow("xxx").VbWindow("xxx").VbLabe1("xxx").GetTOProperty("text")
         str1= VbWindow("xxx").VbWindow("xxx").VbLabel("xxx").GetTOProperty("text")
         comp1=strcomp(strtext1,str,0)
         If  comp=0 Then
              msgbox “这两个串相等”
         else
           msgbox str
         End If

      6.CaptureBitmap

      作用:捕获屏幕

      7. GetROProperty

      作用:取对象属性值

      例:

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

      8.

       ExitAction - 退出当前操作,无论其循环属性如何。
      ExitActionIteration - 退出操作的当前循环。
      ExitRun - 退出测试,无论其循环属性如何。
      ExitGlobalIteration - 退出当前全局循环。

      9.如何使用Excel对象处理数据?

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

      10.连接sql数据库

      例:

         Dim res,cmd,sql
         Set Res=createobject("adodb.recordset")
         Set Cmd=createobject("adodb.command")
         Cmd.activeconnection="Provider=SQLOLEDB.1;Password=111111;Persist Security Info=True;User ID=sa;Initial Catalog=xhq;Data Source=192.168.191.142"  '这句话是连接数据库的数据源,要做修改
        Cmd.CommandType = 1
        sql="selec t * from 表 where name=username"
        Cmd.CommandText = sql
        Set res = Cmd.Execute()
        Set res = nothing
        Set cmd.ActiveConnection = nothing
        Set Cmd= nothing

  • (转)QTP测试页面的连接是否可用

    2009-02-17 09:51:36

     

    set a= Browser(“Yahoo!”)
            set b= Browser(“Yahoo!”)。Page(“Yahoo!”)
            call CheckLinks(a,b)
            Function CheckLinks (BrowserObject,BrowserPage)
            CheckLinks=TRUE
            Dim s_URL,i_CreationTime
            Dim s_LinkOuterText,s_LinkInnerText,s_Linkhref
            s_URL=BrowserPage。GetROProperty(“url”)
            i_CreationTime=1
            i_LinkCount=BrowserPage。object.links。length - 1

            Dim i_Link

            For i_Link=0 to i_LinkCount
            If Trim(BrowserPage。object。links(i_Link)。target)="" Then
            BrowserPage.object.links(i_Link)。target=“_blank" ”‘ Set the link to open i a new window so that we dont have any change in current window
            End If

            BrowserPage。object.links(i_Link)。click
            On error resume next
            Browser(“CreationTime::=” & i_CreationTime)。sync
            Browser(“CreationTime:=” & i_CreationTime)。Page(“micClass:=Page”)。sync
            On error goto 0
            Dim s_LinkDetails

            IHTML = Browser(“CreationTime:=” & i_CreationTime)。Page(“micClass:=Page”)。object。Body。innerHTML
            ‘Check if page was not able to be displayed
            If (InStr(IHTML,“HTTP 404”) 〈〉 0) Or (InStr(IHTML,,“cannot be displayed”) 〈〉 0) Then
            s_LinkDetails=“Link Broken” + vbcrlf + “Link Details:”+vbcrlf
            s_LinkDetails=s_LinkDetails+“OuterText: ”+ s_LinkOuterText + vbcrlf
            s_LinkDetails=s_LinkDetails+“InnerText:”+ s_LinkInnerText + vbcrlf
            s_LinkDetails=s_LinkDetails+ “href:” + s_Linkhref+ vbcrlf
            s_LinkDetails=s_LinkDetails+ “Links Open in New Browse:” & bNewBrowser & vbcrlf
            Reporter。ReportEvent micWarning,“Check Link(“ & i_Link & ”) -> “& s_LinkOuterText ,s_LinkDetails
            CheckLinks=FALSE
            Else
            s_LinkDetails=“Link Working” + vbcrlf + “Link Details:”+vbcrlf
            s_LinkDetails=s_LinkDetails+“OuterText: ”+ s_LinkOuterText + vbcrlf
            s_LinkDetails=s_LinkDetails+“InnerText:”+ s_LinkInnerText+ vbcrlf
            s_LinkDetails=s_LinkDetails+ “href::” + s_Linkhref+ vbcrlf
            s_LinkDetails=s_LinkDetails+ “Links Open in New Browse: ” & bNewBrowser & vbcrlf
            Reporter.ReportEvent micPass,“Check Link(“ & i_Link & ”) -> ”& s_LinkOuterText ,s_LinkDetails
            End If

            Browser(“CreationTime:=1”)。close ‘Close the link open.
            Next
            End Function

  • (转)揭秘QTP的DeviceReplay对象

    2009-02-16 08:46:21

    不知道为什么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

      当我想对UI上的控件做一些特定的操作的时候,例如鼠标左右键点击,键盘输入字符串等,特别是在Object.Set和Object.Type没法使用的时候,DeviceReplay就显得非常有用。]L%}2FB1A |N(^Z ^138711 51Testing软件测试网1so3LU!lJ DMq~ P

    DeviceReplay使用的前提是:51Testing软件测试网6m4Ks?1`m

    51Testing软件测试网Po\HmB o

    1. 应用程序窗口被激活。

    ;Ee{J:zR138711 51Testing软件测试网 |0`5vE'`9[ J*R

    对窗口应用程序: 可以使用Window( "W" ).Activate micLeftBtn

    $[3R"\G$_^)CIA138711 51Testing软件测试网7j0F)R8C2g-f|

    对网页应用程序: 可以使用

    o(gs4X/q138711

    hwnd = Browser( "B" ).GetROProperty( "hwnd" )51Testing软件测试网)j*lB XoW/\

    Window( "hwnd:=" & hwnd ).Activate micLeftBtn51Testing软件测试网0Sf5?ho/A6rd;L v

    c-Ik1UP0x!H1387112. 目标控件为焦点。51Testing软件测试网3FOH"Xp!] G)A

    51Testing软件测试网u!@ w0k+rj;B7q/i

    WebEdit( "WE" ).object.focus 或者 WebEdit( "WE" ).FireEvent "onfocusin"

    h7smk7\ k8Ee2~%x138711

    W.G.c-g(\r[yk8W138711使用以下方法可以判断当前哪些键是否按下:(Microsoft.VisualBasic.Devices.Keyboard

    #H3ee!x_ s Rf138711

    Set Keyboard = DotNetFactory.CreateInstance( "Microsoft.VisualBasic.Devices.Keyboard", "Microsoft.VisualBasic" )51Testing软件测试网5Y"r'Z^.r7_ L

    Print CBool( Keyboard.AltKeyDown )

    d,r&AT8HJ138711

    Print CBool( Keyboard.CapsLock )

    R{.cL7PM(J-\s138711

    Print CBool( Keyboard.CtrlKeyDown )

    ;pGee%n(t,u138711

    Print CBool( Keyboard.NumLock )

    o3e@;G,h"y138711

    Print CBool( Keyboard.ScrollLock )51Testing软件测试网/e8p5tP p)]T$j(N%g]

    Print CBool( Keyboard.ShiftKeyDown )

    &v^4y)lb/~X138711

    +B+T+sf@$|138711注意:使用DotNetFactory的时候要注意数据类型的转换

    \,XX5iSm:Y138711

    Fy2w-f1GU,bi138711使用以下方法可以判断当前鼠标的位置:(System.Windows.Forms.Control)

    0t3kOsS&K(i138711

    Set ctlr = DotNetFactory.CreateInstance("System.Windows.Forms.Control")51Testing软件测试网D c"RWr0w;{^S

    For i = 1 To 10

    l ~ zi8TS:d138711

       Wait 251Testing软件测试网5Aa'F5e7e

       Print "1. X=" & ctlr.MousePosition.X & "; Y=" & ctlr.MousePosition.Y51Testing软件测试网l]*RQ"Urk9HT\d ?

    Next51Testing软件测试网.?/h$k(r'P$@0oieG?

     51Testing软件测试网 P|e*a-iB s

    DeviceReplay有以下常用方法:

    M$P|AFIa6e138711

    1。 object.SendString( str )

    v@r,S9YZ&[138711

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )51Testing软件测试网 d[P)MH8B

    SystemUtil.Run "notepad.exe", "", "", "open"51Testing软件测试网Bz7b5]^

    ' ** this line always identifies the notepad window.

    HLa(Y@6J138711

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

    'U:|6hfAm8[EagH138711

    deviceReplay.SendString( "DeviceReplay" )

    #N)|_2HC3ftP-u138711

    Set deviceReplay = Nothing

    ;O&Tw!r Le|0H138711

    2。 object.KeyDown( key )|object.KeyUp( key )

    h$p*h M ?JC138711

    Const VK_SHIFT = 42

    (bk"]v)y|@#qw138711

    Const VK_RETURN = 28

    'h.mN ot'u3y E:G|138711

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    k{JRO@#P(pR138711

    SystemUtil.Run "notepad.exe", "", "", "open"51Testing软件测试网 r'HC.~0uq ^

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

    y+K`BN)wxWS }u138711

    ' ** Typing uppercase51Testing软件测试网.D1@7N?+}&vw

    deviceReplay.KeyDown VK_SHIFT51Testing软件测试网/y4t&{!I+g9C0P

    deviceReplay.SendString( "devicereplay" )

    #k7w |%DNF#G138711

    deviceReplay.PressKey VK_RETURN

    -~%]'f1Nz&h9e138711

    deviceReplay.KeyUp VK_SHIFT51Testing软件测试网f$e }'`TH ~#v

    ' ** Typing in lower case51Testing软件测试网a9w.[Ju*`1k9b

    deviceReplay.SendString( "devicereplay" )

    :r?:`l O#F138711

    Set deviceReplay = Nothing

    UIx0{ l+BOr s138711

    !H}0pbZ6v;m8n1387113。 object.PressKey( key )51Testing软件测试网9]i5c(A|(E;i/iW

    Const VK_O = 24 : Const VK_F = 33

    #kFC Gl,oHM138711

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

    9X?&|.sV4oxq138711

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )51Testing软件测试网cWJsv

    SystemUtil.Run "notepad.exe", "", "", "open"51Testing软件测试网:pG*B UO

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

    |kV'QFQ*}T)t138711

    Wait 1

    B'Wl4yP:W"C138711

    ' ** Opening the menu Alt + F + O51Testing软件测试网X(V%Tq*SXG

    deviceReplay.PressKey VK_MENU51Testing软件测试网]kV!^#a.c5x CfpJ;`

    deviceReplay.PressKey VK_F

    :C0S9`\8]#b)x138711

    deviceReplay.PressKey VK_O

    9A NJ+C(e&F138711

    Wait 2

    0C%I D:j A+Gp:v138711

    ' ** Closing the menu

    Th-N;Txe%q138711

    deviceReplay.PressKey VK_ESCAPE51Testing软件测试网QK u%Fk,x+z k

    deviceReplay.SendString "Open menu was closed."

    ^4b3Qz-{P B138711

    Set deviceReplay = Nothing51Testing软件测试网ED/a6U8Dpz

    4. object.PressNKeys( key, N )

    R;n+]}$@7}138711


    2`;wI9yAAv |Y138711用于模拟连续多次按某个键。51Testing软件测试网Fl)~C,T]|Fh

    5. object.DragAndDrop( dragX, dragY, dropX, dropY, Button )51Testing软件测试网@'^8GqR_+yw3L

    LEFT_MOUSE_BUTTON = 051Testing软件测试网1H*i @x_

    MIDDLE_MOUSE_BUTTON = 1

    uu'G*AsC!HCT,y138711

    RIGHT_MOUSE_BUTTON = 251Testing软件测试网)gJ,@ |.sg7_5t$B

    等同于object.MouseDown( x, y, Button ), object.MouseDown( x, y ), object.MouseUp( x, y, Button )的组合

    tz#N[)o(y138711

    6. object.MouseClick( x, y, Button )51Testing软件测试网 Fv3l1Ewu!Bw c {Z

    7. object.MouseDblClick( x, y, Button )

    0o'Y%N3BdB"j138711

    8。 object.SetSynchronizationTimeout( object, nSyncTimeout, is_sec)

  • (转)WshShell 对象

    2009-02-02 11:12:16

    WshShell作为WSH对象的一部分,  它的主要任务如下:

    在本地运行程序 操纵注册表内容。 创建快捷方式 访问系统文件夹 操纵环境变量(如 WINDIR、PATH 或 PROMPT)

    1.运行CMD命令行命令

    set ōbshell=wscrīpt.createobject("wscrīpt.shell")

    obshell.run ("ipconfig"),,true

    如果要运行的命令中包含双引号,可使用&chr(34)&代替


    2.操纵注册表内容

    注册表的修改,读取,删除,创建

    Set wso = CreateObject("Wscrīpt.Shell") '声明

    wso.RegWrite "%Path%"               '创建子键

    wso.RegWrite "%Path%","%Value%"     '修改"默认"键值

    wso.RegWrite "%Path%",%Value%,%RegType%   '修改特定类型的键值

    '(字符串值 REG_SZ 可扩充字符串值 REG_EXPAND_SZ DWORD值 REG_DWORD 二进制值 REG_BINARY)

    Set WSHShell= Wscrīpt.CreateObject("Wscrīpt.Shell")

    WSHShell.RegRead (%Path%) '读取注册表子键或键值(一般用于判断某一事件是否执行)

    Set wso = CreateObject("Wscrīpt.Shell")

    wso.RegDelete "%Path%" '删除子键或键值

    '(根键缩写HKEY_CLASSES_ROOT HKCR HKEY_CURRENT_USER HKCU HKEY_LOCAL_MACHINE HKLM,其余无)

    Set wso = CreateObject("Wscrīpt.Shell")

    wso.RegWrite "HKLM\SOFTWARE\Microsft\Windows NT\#1"

    wso.RegWrite "HKLM\SOFTWARE\Microsft\Windows NT\#1","0"

    wso.RegWrite "HKLM\SOFTWARE\Microsft\Windows NT\#1\#2",0,REG_BINARY

    wso.RegDelete "HKLM\SOFTWARE\Microsft\Windows NT\#1"

    Wscrīpt.quit

    3.创建快捷方式
    Set a = CreateObject("Wscrīpt.Shell")

    Dim b
    Set b = a.CreateShortcut("C:\lin.lnk")
    b.TargetPath = "notepad.exe"
    b.WorkingDirectory = "C:\windows\system32"
    b.IconLocation = "notepad.exe,0"
    b.Save

     


    4.访问系统文件夹

    文件的复制,删除,创建,简单的写入

    Set fso = Wscrīpt.CreateObject("scrīpting.FileSystemObject") ‘声明

    Set f = fso.CreateTextFile("%PATH%") '创建文件,其中f可任意,包含缩略名

    f.WriteLine("VBS") '写文件内容,该命令功能太简单,目前看来只能用于TXT文件

    f.Close

    set c=fso.getfile("%path%") ’拷贝某文件

    c.copy("%PATH2%") '拷贝文件到指定地点

    fso.deletefile("%PATH%") '删除文件

    Wscrīpt.quit

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

    Set f=fso.CreateTextFile("C:\Sample.txt")

    WriteLine("VBS")

    f.close

    set e=fso.getfile(C:\Sample.txt)

    e.copy("D:\Sample.txt")

    fso.deletefile(C:\Sample.txt)

    Wscrīpt.quit

    5.操纵环境变量(如 WINDIR、PATH 或 PROMPT)

    dim wsh
    Set wsh = Wscrīpt.CreateObject("Wscrīpt.Shell")
    wsh.Environment("system").Item("<变量名>")="<值>"
    或使用使用REG
    set regpath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
    ::系统环境变量
    ::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
    ::用户环境变量
    ::HKEY_CURRENT_USER\Environment
    reg add "%regpath%" /v "<name>" /d "<data>"
    将上面的<>内容替成你需要定义的名称和值就可以了.

    6.向应用程序输出简单的连串指令

    dim program1 '声明变量program1

    program1= "%Path%" '应用程序路径

    set wshshell=createobject("wscrīpt.shell") '声明饮用函数

    set ōexec=wshshell.exec(program1) '运行程序

    wscrīpt.sleep 2000 '(该行命令未知作用.估计是设定延迟,请高手指点)

    wshshell.appactivate "%WindowsName%" '激活运用程序窗口

    wshshell.sendkeys "+{%KeyBoardName%}" '第一次输出键盘按键指令前要加+

    wshshell.sendkeys "555555" '在程序输入栏中输入运用该系列命令须首先确定程序可以实施连串的键盘操作,这在QQ登录中最适用,如下例。

    dim program1

    program1="D:\Program Files\Tencent\coralQQ.exe"

    set wshshell=CreateObject("wscrīpt.shell")

    set ōexec=wshshell.exec(program1)

    wscrīpt.sleep 2000

    wshshell.appactivate "QQ登录"

    wshshell.sendkeys "+{TAB}"

    wshshell.sendkeys "250481892"

    wscrīpt.sleep 2000

    wshshell.sendkeys "{TAB}"

    wshshell.sendkeys "****************"

  • (转)SQL 连接 JOIN 例解。(左连接,右连接,全连接,内连接,交叉连接,自连接)

    2009-01-21 10:20:58

    最近公司在招人,同事问了几个自认为数据库可以的应聘者关于库连接的问题,回答不尽理想~
    现在在这写写关于它们的作用
    假设有如下表:


    一个为投票主表,一个为投票者信息表~记录投票人IP及对应投票类型,左右连接实际说是我们联合查询的结果以哪个表为准~
    1:如右接连 right join 或 right outer join:

    我们以右边voter表为准,则左表(voteMaster)中的记录只有当其ID在右边(voter)中存在时才会显示出来,如上图,左边中ID为3.4.5.6因为这些ID右表中没有相应记录,所以没有显示!
    2:因此我们自然能理解左连接 left join 或者 left outer join

    可见,现在右边中ID在中存在时才会显示,当右边中没有相应数据时则用NULL代替!
    3:全连接 full join 或者 full outer join,为二个表中的数据都出来,这里演示效果与上一样!
    4:内连接 inner join 或者 join;它为返回字段ID同时存在于表voteMaster 和 voter中的记录

    5:交叉连接(完全连接)cross join 不带 where 条件的
    没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生6*3=18条记录)

    等价select vm.id,vm.voteTitle,vt.ip from voteMaster as vm,voter as vt

    6:自连接。在这里我用我前段时间一个电力项目中的例子(改造过)
    如下表:

    这是一个部门表,里面存放了部门及其上级部门,但都放在同一张表中,我们假设现在需要用SQL查询出各部门及其上级部门!就如何做,
    当然,不用自连接也一样,可以如下:

    我们达到预期目的!在这个查询中使用了一个子查询完成对上级部门名的查询,如果使用自连接,那么结构上感觉会清晰很多。

    是不是也同样完成了功能呢,这里除了使用自连接外,还使用了左连接,因为省电力没有上级部门,他是老大,如果使用内连接,就会把这条记录过滤掉,因为没有和他匹配的上级部门。
    自连接用的比较多的就是对权形结构的查询!类似上表!
  • (转)面试中要懂的SQL语句

    2009-01-20 16:43:23

    面试必须要知道的SQL语法,语句
    前言:书里有的、书里没的,统统在此可以一浏。
    asc 按升序排列
    desc 按降序排列
    下列语句部分是Mssql语句,不可以在access中使用。
    SQL分类:
    DDL—数据定义语言(Create,Alter,Drop,DECLARE)
    DML—数据操纵语言(Select,Delete,Update,Insert)
    DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)
    首先,简要介绍基础语句:
    1、说明:创建数据库
    Create DATABASE database-name
    2、说明:删除数据库
    drop database dbname
    3、说明:备份sql server
    --- 创建 备份数据的 device
    USE master
    EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
    --- 开始 备份
    BACKUP DATABASE pubs TO testBack
    4、说明:创建新表
    create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
    根据已有的表创建新表:
    A:create table tab_new like tab_old (使用旧表创建新表)
    B:create table tab_new as select col1,col2… from tab_old definition only
    5、说明:删除新表drop table tabname
    6、说明:增加一个列
    Alter table tabname add column col type
    注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。
    7、说明:添加主键: Alter table tabname add primary key(col)
    说明:删除主键: Alter table tabname drop primary key(col)
    8、说明:创建索引:create [unique] index idxname on tabname(col….)
    删除索引:drop index idxname
    注:索引是不可更改的,想更改必须删除重新建。
    9、说明:创建视图:create view viewname as select statement
    删除视图:drop view viewname
    10、说明:几个简单的基本的sql语句
    选择:select * from table1 where 范围
    插入:insert into table1(field1,field2) values(value1,value2)
    删除:delete from table1 where 范围
    更新:update table1 set field1=value1 where 范围
    查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
    排序:select * from table1 order by field1,field2 [desc]
    总数:select count as totalcount from table1
    求和:select sum(field1) as sumvalue from table1
    平均:select avg(field1) as avgvalue from table1
    最大:select max(field1) as maxvalue from table1
    最小:select min(field1) as minvalue from table1
    11、说明:几个高级查询运算词
    A: UNION 运算符
    UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。
    B: EXCEPT 运算符
    EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。
    C: INTERSECT 运算符
    INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
    注:使用运算词的几个查询结果行必须是一致的。
    12、说明:使用外连接
    A、left outer join:
    左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
    sql: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
    B:right outer join:
    右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
    C:full outer join:
    全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。
    其次,大家来看一些不错的sql语句
    1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)
    法一:select * into b from a where 1<>1
    法二:select top 0 * into b from a
    2、说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)
    insert into b(a, b, c) select d,e,f from b;
    3、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)
    insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件
    例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..
    4、说明:子查询(表名1:a 表名2:b)
    select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)
    5、说明:显示文章、提交人和最后回复时间
    select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
    6、说明:外连接查询(表名1:a 表名2:b)
    select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
    7、说明:在线视图查询(表名1:a )
    select * from (Select a,b,c FROM a) T where t.a > 1;
    8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括
    select * from table1 where time between time1 and time2
    select a,b,c, from table1 where a not between 数值1 and 数值2
    9、说明:in 的使用方法
    select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)
    10、说明:两张关联表,删除主表中已经在副表中没有的信息
    delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )
    11、说明:四表联查问题:
    select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
    12、说明:日程安排提前五分钟提醒
    sql: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5
    13、说明:一条sql 语句搞定数据库分页
    select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段
    14、说明:前10条记录
    select top 10 * form. table1 where 范围
    15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)
    select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)
    16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表
    (select a from tableA ) except (select a from tableB) except (select a from tableC) 17、说明:随机取出10条数据
    select top 10 * from tablename order by newid()

    18、说明:随机选择记录
    select newid()

    19、说明:删除重复记录
    Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

    20、说明:列出数据库里所有的表名
    select name from sysobjects where type='U'

    21、说明:列出表里的所有的
    select name from syscolumns where id=object_id('TableName')

    22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。
    select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
    显示结果:
    type vender pcs
    电脑 A 1
    电脑 A 1
    光盘 B 2
    光盘 A 2
    手机 B 3
    手机 C 3

    23、说明:初始化表table1

    TRUNCATE TABLE table1

    24、说明:选择从10到15的记录
    select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
      
    随机选择数据库记录的方法(使用Randomize函数,通过SQL语句实现)
      对存储在数据库中的数据来说,随机数特性能给出上面的效果,但它们可能太慢了些。你不能要求ASP“找个随机数”然后打印出来。实际上常见的解决方案是建立如下所示的循环:
    Randomize
    RNumber = Int(Rnd*499) +1
     
    While Not objRec.EOF
    If objRec("ID") = RNumber THEN
    ... 这里是执行脚本 ...
    end if
    objRec.MoveNext
    Wend
     
      这很容易理解。首先,你取出1到500范围之内的一个随机数(假设500就是数据库内记录的总数)。然后,你遍历每一记录来测试ID 的值、检查其是否匹配RNumber。满足条件的话就执行由THEN 关键字开始的那一块代码。假如你的RNumber 等于495,那么要循环一遍数据库花的时间可就长了。虽然500这个数字看起来大了些,但相比更为稳固的企业解决方案这还是个小型数据库了,后者通常在一个数据库内就包含了成千上万条记录。这时候不就死定了?
      采用SQL,你就可以很快地找出准确的记录并且打开一个只包含该记录的recordset,如下所示:
    Randomize
    RNumber = Int(Rnd*499) + 1
     
    sql = "Select * FROM Customers Where ID = " & RNumber
     
    set ōbjRec = ObjConn.Execute(SQL)
    Response.WriteRNumber & " = " & objRec("ID") & " " & objRec("c_email")
     
      不必写出RNumber 和ID,你只需要检查匹配情况即可。只要你对以上代码的工作满意,你自可按需操作“随机”记录。Recordset没有包含其他内容,因此你很快就能找到你需要的记录这样就大大降低了处理时间。
    再谈随机数
      现在你下定决心要榨干Random 函数的最后一滴油,那么你可能会一次取出多条随机记录或者想采用一定随机范围内的记录。把上面的标准Random 示例扩展一下就可以用SQL应对上面两种情况了。
      为了取出几条随机选择的记录并存放在同一recordset内,你可以存储三个随机数,然后查询数据库获得匹配这些数字的记录:
    sql = "Select * FROM Customers Where ID = " & RNumber & " or ID = " & RNumber2 & " or ID = " & RNumber3
     
      假如你想选出10条记录(也许是每次页面装载时的10条链接的列表),你可以用BETWEEN 或者数学等式选出第一条记录和适当数量的递增记录。这一操作可以通过好几种方式来完成,但是 Select 语句只显示一种可能(这里的ID 是自动生成的号码):
    sql = "Select * FROM Customers Where ID BETWEEN " & RNumber & " AND " & RNumber & "+ 9"

      注意:以上代码的执行目的不是检查数据库内是否有9条并发记录。

     
    随机读取若干条记录,测试过
    Access语法:Select top 10 * From 表名 orDER BY Rnd(id)
    sql server:select top n * from 表名 order by newid()
    mysqlelect * From 表名 order By rand() Limit n
    Access左连接语法(最近开发要用左连接,Access帮助什么都没有,网上没有Access的SQL说明,只有自己测试, 现在记下以备后查)
    语法elect table1.fd1,table1,fd2,table2.fd2 From table1 left join table2 on table1.fd1,table2.fd1 where ...
    使用SQL语句 用...代替过长的字符串显示
    语法:
    SQL数据库:select case when len(field)>10 then left(field,10)+'...' else field end as news_name,news_id from tablename
    Access数据库:Select iif(len(field)>2,left(field,2)+'...',field) FROM tablename;
     
    Conn.Execute说明
    Execute方法
      该方法用于执行SQL语句。根据SQL语句执行后是否返回记录集,该方法的使用格式分为以下两种:

    1.执行SQL查询语句时,将返回查询得到的记录集。用法为:
        Set 对象变量名=连接对象.Execute("SQL 查询语言")
       Execute方法调用后,会自动创建记录集对象,并将查询结果存储在该记录对象中,通过Set方法,将记录集赋给指定的对象保存,以后对象变量就代表了该记录集对象。

        2.执行SQL的操作性语言时,没有记录集的返回。此时用法为:
        连接对象.Execute "SQL 操作性语句" [, RecordAffected][, Option]
          ·RecordAffected 为可选项,此出可放置一个变量,SQL语句执行后,所生效的记录数会自动保存到该变量中。通过访问该变量,就可知道SQL语句队多少条记录进行了操作。
          ·Option 可选项,该参数的取值通常为adCMDText,它用于告诉ADO,应该将Execute方法之后的第一个字符解释为命令文本。通过指定该参数,可使执行更高效。

    ·BeginTrans、RollbackTrans、CommitTrans方法
      这三个方法是连接对象提供的用于事务处理的方法。BeginTrans用于开始一个事物;RollbackTrans用于回滚事务;CommitTrans用于提交所有的事务处理结果,即确认事务的处理。
      事务处理可以将一组操作视为一个整体,只有全部语句都成功执行后,事务处理才算成功;若其中有一个语句执行失败,则整个处理就算失败,并恢复到处里前的状态。
      BeginTrans和CommitTrans用于标记事务的开始和结束,在这两个之间的语句,就是作为事务处理的语句。判断事务处理是否成功,可通过连接对象的Error集合来实现,若Error集合的成员个数不为0,则说明有错误发生,事务处理失败。Error集合中的每一个Error对象,代表一个错误信息。
  • (转)SQLSERVER和ORACLE数据库连接代码

    2009-01-20 09:57:56


    1、Oracle数据库

    要求在客户端机器上安装了oracle客户端并已配置完成

    代码:

    Set Conn = CreateObject("ADODB.CONNECTION")
    StrCon = "Provider=OraOLEDB.Oracle.1;Persist Security Info=True;" &_
      "User ID=xxx;Password=xxx;Data Source=xxxx;"
    Conn.Open StrCon

    SqlStr = "select number from table"
    Set Res = CreateObject("ADODB.RecordSet")
    Res.Open SqlStr,Conn,1,1

    2、sqlserver数据库

      Dim rs,conn,sqlstr,strcon

      strcon = "Provider=SQLOLEDB.1;User ID=sa;Password=xxxx;"&_
    "Data source=10.10.7.11;DATABASE=qcsiteadmin_db"

      Set conn = createobject("adodb.connection")
      conn.open strconn

      sqlstr="select * from td.SESSIONS_HISTORY where USER_NAME = '"_
         &LOGINUSER&"'"

      Set rs=createobject("adodb.recordset")
       rs.open sqlstr,conn,1,1

Open Toolbar