转载一切对自己或大家有用的东西,如有雷同,不是原创就是转载的

发布新日志

  • 揭秘QTP的DeviceReplay对象

    2009-02-17 16:50:55

    为什么要用DeviceReplay

    有些时候我们需要针对界面做一些指定的动作,例如右键单击一个对象,使用功能键(Fx)来激活某些热键的功能,这时候就可以使用DeviceReplay对象,或者在Object.SetObject.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.focusWebEdit(“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方法

    描述

    模拟一个按键的按下并保持(相当于Win32KEY_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

    deviceReplay.PressKey VK_TAB

    If Len( state ) < 8 Then

    deviceReplay.PressKey VK_TAB

    End If

    deviceReplay.SendString usps

    deviceReplay.PressKey VK_TAB

    deviceReplay.SendString capital

    deviceReplay.PressKey VK_RETURN

    End Sub

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

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

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

    ' ** Setup Notepad - Font courier new, size 14,

    ' ** NUM-LOCK pressed and CAPS-LOCK unpressed

    Call SetupKeyboard()

    Call SetupNotepad()

    ' ** inserting date

    deviceReplay.PressKey VK_F5

    deviceReplay.PressKey VK_RETURN

    ' ** Inserting Title

    deviceReplay.PressNKeys VK_TAB, 3

    deviceReplay.SendString "

  • QTP识别和操作对象的原理

    2009-02-17 16:49:14

    转自51论坛网友yabest的文章.

    呵呵,这个文章本来是在给别人的帖《GetROProperty,GetTOProperties,GetTOProperty的区别 》回复时写的,没有独立出来。
    http://bbs.51testing.com/viewthread.php?tid=13554&page=1#pid369327
    写完后,在网上被多处转载。没想到今天又被转贴回51testing来了。

    虽然在精华版里,也赚了几朵花,但没独立总是不方便。所以修整了一下,独立成帖,以方便大家阅读。
    欢迎大家拍砖!(当然更欢迎大家送花sdlkfj5)


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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

     

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

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

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


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

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

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

    比如操作JavaEdit对象,通过QTP封装的封装接口,脚本如下:
      设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").Set "NE1"
      读取JavaEdit的内容:
         msgbox JavaDialog("Add NE").JavaEdit("NE Name").GetROProperty("value")

    如果通过JavaEdit的自身接口,脚本如下:
      设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").object.setText("NE1")
      读取JavaEdit的内容:
         Msgbox JavaDialog("Add NE").JavaEdit("NE Name").object.getText()

    QTP执行JavaEdit().Set语句时,是通过执行JavaEdit().object.setText()来实现的。
    QTP执行JavaEdit().GetROProperty("value"),是通过执行JavaEdit().object.getText()来实现的。
    JavaEdit对象的封装接口Set()和GetROProperty("value"),是QTP封装JavaEdit对象的自身接口setText()和getText()而得来的。

    对象的封装接口是QTP使用的缺省接口,我们录制出来的脚本都是使用封装接口,大家用的也都是封装接口。
    但是封装接口不如自身接口丰富,因为QTP只是封装了部分常用的自身接口嘛。
    所以我们在需要时,可以绕过封装接口,直接调用对象的自身接口。
    不过有些自身接口不够稳定,在实践中偶尔会出现问题,但是概率很少。
    封装接口有相应功能的话,就尽量用封装接口吧!
    ( Written by yabest,http://www.yabest.net

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

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

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


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

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

    你可以拿这个做恶作剧,指着这个窗口逼问开发人员,JavaEdit对象哪去了?

  • 模拟鼠标右键

    2008-10-21 12:04:56

    Set x = createobject("wscrīpt.shell")
    cur_replay_type = Setting.WebPackage("ReplayType")
    Setting.WebPackage("ReplayType") = 2
    browser("Google").Page("Google").WebEdit("q").Click ,,micRightBtn
    For i = 1 to 4
     wait(1)
       x.sendkeys "{DOWN}"
    Next
    x.sendkeys "{ENTER}"
    Set x = nothing
    Setting.WebPackage("ReplayType") = cur_replay_type
    'browser("Google").Page("Google").WebEdit("q").Click ,,2
  • IE浏览器的最大最小化

    2008-10-21 11:57:31

    'Open an IE browser with the method CreateObject()
    Dim objIE, hwndIE
     Set ōbjIE = CreateObject("internetexplorer.application")
    objIE.Visible = true
    objIE.Navigate "http://www.google.cn" 'The parameter URL is the destination address for the IE browser

    'Wait a while till the page is fully loaded
    Wait(10)

    'Move and resize the browser
    hwndIE = objIE.HWND
    'Operate the IE browser as a window object with descrīptive programming
    'The window object can be uniquely identified by the parameter hwndIE, which is the window's handle of the browser
    'Window ("hwnd:=" & hwndIE).Minimize
    Window ("hwnd:=" & hwndIE).Maximize

    'Release the object after the adjustment
    Set ōbjIE = nothing

     

  • DeviceReplay对象使用

    2008-08-14 11:49:27

    Function Mouse_Click(x , y)
        Dim device
        Set MouseObject = CreateObject("Mercury.DeviceReplay")
        MouseObject.MouseMove x , y
        MouseObject.MouseClick x , y , LEFT_MOUSE_BUTTON
    End Function

     

    DeviceReplay很实用的一个对象

    这个对象用来模拟鼠标的单击和移动、键盘输入等,但有个前提,实用该对象前,需要保证键盘状态正确

    如NUMLOCK是否打开等,因为DeviceReplay不能检测键盘状态

    Mercury.DeviceReplay方法如下:

    1、SendString方法

    向激活的窗口发送一个或多个键盘按键:object.SendString( str )

    2、KeyDown方法

    模拟一个按键的按下并保持:object.KeyDown( key )   key 按键的数值码

    3、KeyUp方法

    模拟通过键盘释放某个按下的按键:object.KeyUp( key )

    4、PressKey方法

    模拟通过键盘按下一个按键并立即释放:object.PressKey( key )

     

    5、PressNKeys方法

     

    模拟通过键盘多次按下一个按键并立即释放:object.PressNKey( key, N )  N:重复次数

     

    6、DragAndDrop方法

     

    用于执行从一点拖动到另外一点的操作:object.DragAndDrop( dragX, dragY, dropX, dropY, Button )

    Button 的值包括

    LEFT_MOUSE_BUTTON = 0

    MIDDLE_MOUSE_BUTTON = 1

     RIGHT_MOUSE_BUTTON = 2

     

    7、MouseClick方法

     

    在指定的屏幕位置执行鼠标左键或右键的单击操作:object.MouseClick( x, y, Button )

     

    8、MouseDbClick方法

     

    在指定的屏幕位置中执行鼠标左键或右键的双击事件:object.MouseDblClick( x, y, Button )

     

    9、MouseDown方法

     

    在屏幕指定位置按下鼠标左键或右键,并保持按下状态:object.MouseDown( x, y, Button )

     

    10、MouseUp方法

     

    用于释放之前执行的MouseDown方法所按下的鼠标按键:object.MouseDown( x, y, Button )

     

    11、MouseMove方法

     

    用于模拟鼠标移动:object.MouseMove( x, y)

     

    12、SetSynchronizationTimeout方法

     

    设置一个新的同步超时的时间值:object. SetSynchronizationTimeoutnSyncTimeout , is_sec

    nSyncTimeout 同步超时的时间值。

    is_sec 指定设置的时间值是否以秒为单位

Open Toolbar