zoukankan      html  css  js  c++  java
  • 老李分享:QTP的录制原理以及实现

    老李分享:QTP的录制原理以及实现

     

        poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。如果对课程感兴趣,请大家咨询qq:908821478。 

        以前在培训的时候要讲quicktestprofessional的自动化测试,其中要讲qtp的原理,网上有很多文章是把qtp操作过程当成原理来讲,觉得有些可笑,另外在我也听过同事和一些公司资深专家讲实现原理,但是都是含糊其词,说不清楚。我在上课的时候会讲qtp的原理,qtp的实现分为两大核心部分:录制和回放,今天我主要讲讲录制的原理性的东西,并贴一个小案例代码,用Python实现,因为Poptest培训主要提高和强化测试开发能力。

     我们知道qtp主要是windows平台上的自动化测试工具,所以需要学员了解windows底层的一些东西在这里主要涉及到两方面win32消息机制和hook技术。录制的核心是把在被测试软件系统上的所有操作记录下来。

       我们先要了解下windows系统的消息机制的原理,消息机制和绘图机制是微软Windows及其周边其它产品与生俱来的,是Win系列OS作为一个操作系统进行微机内部实现的二大支柱和特征。

       消息系统是Windows下一切应用程序间,包括Windows自身,进行交互和通讯的渠道,是Windows实现对运行在其下的所有应用程序进行控制及应用程序对Windows进行响应的解决手段。消息的产生来源于系统事情(包括计时器事件)和用户事件,Windows用消息来调入和关闭(还有其它处理,如绘制一个窗口等)应用程序,一个典型表现是在关机操作中,Windows发一个关机的消息给所有正在运行的应用程序,告知它们退出内存,此时,应用程序用回应消息的方法来响应OS,因此,消息是应用程序与WinOS交互的手段。消息的主体是应用程序之间和应用程序与 OS 之间,(这是通俗的说法,其实在一个应用程序的内部,各“窗口”组件之间也存在着消息的流动,窗口组件与它们的父窗口和上层窗口之间当然也有消息的传递过程(如"命令传递",后面在跟踪一个消息的路径中将会详谈),Windows内部即时流动的消息数量是如此的宠大,程序实现之外的手工分析是一种很自不量力的事情)消息的最终主体却是窗口与窗口之间,窗口与OS之间。简单地说,Windows是由事件驱动的抢占式多任务操作系统。事件驱动是相对于过程驱动而言的,它改变了原来文件的顺序执行方式;Windows既然是多任务系统,就必须能同时处理多个事件,系统为应用程序生成一个消息队列,消息在上面被张贴和发送,应用程序只要从其消息队列中取出消息,然后一一执行就可以了。

      我们来进一步看WINDOWS的消息机制,Windows系统是以消息处理为其控制机制,系统通过消息为窗口过程(windows  procedure)传递输入。系统和应用两者都可以产生消息。对于每个输入事件,例如用户按下了键盘上的某个键、移动了鼠标、单击了一个控件上的滚动条,等等,系统都将产生一系列消息。此外,对于应用带给系统的变化,如字体资源的改变、应用本身窗口的改变,系统都将通过消息以响应这种变化。应用通过产生消息指示应用的窗口

    完成特定的任务,或与其他应用的窗口进行通信。每个窗口都有一个处理Windows系统发送消息的处理程序,称为窗口程序。它是隐含在窗口背后的一段程序脚本,其中包含对事件进行处理的代码。Windows系统为每条消息指定了一个消息编号,例如当一个窗口变为活动窗口时,它事实上是收到一条来自Windows系统的WM_ACTIVATE消息,该消息的编号为6,它对应于窗口的Activate事件。对于窗口来说,诸如Open、Activate、MouseDown、Resize

    等事件,实际上对应的是窗口内部的消息处理程序,这些程序对于用户来讲是不可见的。 类似地,命令按钮也有消息处理程序,它的处理程序响应诸如WM_LBUTTONDOWN 和WM_RBUTTONDOWN之类的消息,即激活命令按钮的MouseDown事件。

        WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种回调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上 可以挂接多个反调函数构成一个挂接函数链。系统产生的各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交还控 制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOW系统的这种反调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有用的,通过合理有效地利用键盘事件的挂钩函数监控机制可以达到预想不到的良好效果。

      

    hook技术也就是我们说的钩子,是WINDOWS提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。注意:安装钩子函数将会影响系统的性能。监测“系统范围事件”的系统钩子特别明显。因为系统在处理所有的相关事件时都将调用您的钩子函数,这样您的系统将会明显的减慢。所以应谨慎使用,用完后立即卸载。还有,由于您可以预先截获其它进程的消息,所以一旦您的钩子函数出了问题的话必将影响其它的进程。记住:功能强大也意味着使用时要负责任。

     HOOK会涉及到hook链,WINDOWS提供了14种不同类型的HOOKS;不同的HOOK可以处理不同的消息。例如,WH_MOUSE HOOK用来监视鼠标消息。WINDOWS为这几种HOOKS维护着各自的HOOK链表。HOOK链表是一串由应用程序定义的回调函数(CALLBACK Function)队列,当某种类型的消息发生时,WINDOWS向此种类型的HOOK链的第一个函数(HOOK链的顶部)发送该消息,在第一函数处理完该消息后由该函数向链表中的下一个函数传递消息,依次向下。如果链中某个函数没有向下传送该消息,那么链表中后面的函数将得不到此消息。(对于某些类型的HOOK,不管HOOK链中的函数是否向下传递消息,与此类型HOOK联系的所有HOOK函数都会收到系统发送的消息)一些Hook子过程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子过程或者目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。

       poptest(www.poptest.cn)在课堂上已经转为python作为主要学习语言,自动化测试性能测试也通过自己开发测试工具来完成,所以这里用python实现键盘监控,F12终止程序的功能,需要安装pyhooks,代码如下:

    # -*- coding: cp936 -*-

    import pythoncom 

    import pyHook 

    import time

    import win32api

    t=''

    asciistr=''

    keystr=''

    def onKeyboardEvent(event):  

        global t,asciistr,keystr

        filename='d://test.txt'

        wrfile=open(filename,'ab')

        "处理键盘事件"

        if t==str(event.WindowName):

            asciistr=asciistr+chr(event.Ascii)

            keystr=keystr+str(event.Key)

            

        else:

            t=str(event.WindowName)

            if asciistr=='' and keystr=='':

                wrfile.writelines(" Window:%s " % str(event.Window))

                wrfile.writelines("WindowName:%s " % str(event.WindowName)) #写入当前窗体名

                wrfile.writelines("MessageName:%s " % str(event.MessageName))

                wrfile.writelines("Message:%d " % event.Message)

                wrfile.writelines("Time:%s " % time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))

            else:

                wrfile.writelines("Ascii_char:%s " %asciistr)

                wrfile.writelines("Key_char:%s " %keystr)

                wrfile.writelines(" Window:%s " % str(event.Window))

                wrfile.writelines("WindowName:%s " % str(event.WindowName)) #写入当前窗体名

                wrfile.writelines("Time:%s " % time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))

            

            asciistr=chr(event.Ascii)

            keystr=str(event.Key)

        if str(event.Key)=='F12':  #按下F12后终止

            wrfile.writelines("Ascii_char:%s " %asciistr)

            wrfile.writelines("Key_char:%s " %keystr)

            wrfile.close()   

            win32api.PostQuitMessage()

            

        return True

    if __name__ == "__main__":

        #创建hook句柄 

        hm = pyHook.HookManager() 

        #监控键盘 

        hm.KeyDown = onKeyboardEvent 

        hm.HookKeyboard() 

        #循环获取消息 

        pythoncom.PumpMessages(10000)   

  • 相关阅读:
    初识MySQL
    正则表达式
    多线程
    多进程
    Python基础--模块
    Python基础--异常
    Python基础--面向对象
    Python基础--文件操作
    Python基础--函数
    python3 日期时间差计算
  • 原文地址:https://www.cnblogs.com/poptest/p/4904593.html
Copyright © 2011-2022 走看看