自动化测试框架: 控制界面的关键
2007-05-27 00:17
225 查看
前面讲到要做一体化自动化测试框架,那么,最重要的是要解决什么呢?
相信了解Windows编程的人员,都能发现这个问题所在。在窗体中,写下代码,控制每一个控件的输入是非常简单的事。但是,一旦显示了一个模态窗体,原有的流程代码会不再往下执行,而是停留在新窗体中,等待消息相应。这就是我们代码控制界面的关键问题。
这是什么道理呢?
我使用的是Delphi系统,所以我可能使用VCL框架来解释这个问题。但是其他语言同样适用。
在Windows程序中,WinMain是入口。而WinMain的处理,就是一个典型的死循环,先从消息队列中取出消息,然后再给各窗体派发消息。
为了方便理解,我们将这个模型简化,就是一个死循环A。中间在处理任意的代码。
现在,由于调用了某一段处理,进入了另外一个死循环B。当代码从A函数进入了B,那么当然,A循环下面的代码当然只能停留下来,直到B循环结束。
而在Windows界面中,模态窗体就是一个消息死循环。当Windows弹出一个模态窗体的时候,其消息队列独立处理,不再走整个应用程序的消息循环。
现在比较明白了,不能方便控制界面的原因在于Windows应用程序并不是流程化的,而是消息驱动的。
明白了这个道理,就有可能找到突破口。我想到了钩子。在Delphi中使用钩子,推荐使用FastCode。
既然程序从A循环进入到B循环,我不能继续执行A循环的代码,那么,可不可以在进入B循环后,继续执行A的代码呢?
这应该是可行的。关键在于我必须做到B循环中,能够调用到我的代码。
在Delphi的一般窗体,你可以通过使钩子Hook住TForm的DoShow方法。那样,窗体不管是否是ShowModal的,都会触发,然后通过给此窗体发送一个特殊消息,并在此窗体中,使用钩子,处理此消息。那么就可以在窗体完全显示之后,真正处理你的任务了。这里有一个技巧,窗体真正显示,并不是调用DoShow的时候,而是经过Windows的消息循环,完全处理好所有显示相关消息之后。这里,通过消息循环机制,给它发送一个额外消息,那么可以保障,触发你的任务的时机,是在窗体处理完原有消息之后。
当然了,在VCL中,并不是这么简单就能处理所有问题。最主要的是那些标准Windows窗体,比如MessageBox,OpenDialog。这些窗体不是由TForm组合而成的。所以对象和消息机制都不一样。需要单独处理。
这里有一种方式,是通过定时器,定时查询活动窗体状态。如果检测到非标准Windows窗体,手动触发你的任务。也是一种权衡解决方式。
由于代码版权问题,我这里不能贴出这些代码,不过主要意思应该都讲清楚了吧。
总结以下这个关键点:
消息机制和流程代码的冲突,是根本原因
简单的模型,就是循环嵌套循环问题
使用钩子,在循环开始处,触发任务
这样,基本就可以控制界面了。
相信了解Windows编程的人员,都能发现这个问题所在。在窗体中,写下代码,控制每一个控件的输入是非常简单的事。但是,一旦显示了一个模态窗体,原有的流程代码会不再往下执行,而是停留在新窗体中,等待消息相应。这就是我们代码控制界面的关键问题。
这是什么道理呢?
我使用的是Delphi系统,所以我可能使用VCL框架来解释这个问题。但是其他语言同样适用。
在Windows程序中,WinMain是入口。而WinMain的处理,就是一个典型的死循环,先从消息队列中取出消息,然后再给各窗体派发消息。
为了方便理解,我们将这个模型简化,就是一个死循环A。中间在处理任意的代码。
现在,由于调用了某一段处理,进入了另外一个死循环B。当代码从A函数进入了B,那么当然,A循环下面的代码当然只能停留下来,直到B循环结束。
而在Windows界面中,模态窗体就是一个消息死循环。当Windows弹出一个模态窗体的时候,其消息队列独立处理,不再走整个应用程序的消息循环。
现在比较明白了,不能方便控制界面的原因在于Windows应用程序并不是流程化的,而是消息驱动的。
明白了这个道理,就有可能找到突破口。我想到了钩子。在Delphi中使用钩子,推荐使用FastCode。
既然程序从A循环进入到B循环,我不能继续执行A循环的代码,那么,可不可以在进入B循环后,继续执行A的代码呢?
这应该是可行的。关键在于我必须做到B循环中,能够调用到我的代码。
在Delphi的一般窗体,你可以通过使钩子Hook住TForm的DoShow方法。那样,窗体不管是否是ShowModal的,都会触发,然后通过给此窗体发送一个特殊消息,并在此窗体中,使用钩子,处理此消息。那么就可以在窗体完全显示之后,真正处理你的任务了。这里有一个技巧,窗体真正显示,并不是调用DoShow的时候,而是经过Windows的消息循环,完全处理好所有显示相关消息之后。这里,通过消息循环机制,给它发送一个额外消息,那么可以保障,触发你的任务的时机,是在窗体处理完原有消息之后。
当然了,在VCL中,并不是这么简单就能处理所有问题。最主要的是那些标准Windows窗体,比如MessageBox,OpenDialog。这些窗体不是由TForm组合而成的。所以对象和消息机制都不一样。需要单独处理。
这里有一种方式,是通过定时器,定时查询活动窗体状态。如果检测到非标准Windows窗体,手动触发你的任务。也是一种权衡解决方式。
由于代码版权问题,我这里不能贴出这些代码,不过主要意思应该都讲清楚了吧。
总结以下这个关键点:
消息机制和流程代码的冲突,是根本原因
简单的模型,就是循环嵌套循环问题
使用钩子,在循环开始处,触发任务
这样,基本就可以控制界面了。
相关文章推荐
- 自动化测试框架: 控制界面的关键
- 自动化测试框架: 控制界面的关键
- 自动化测试框架: 控制界面的关键
- 自动化测试框架: 控制界面的关键
- 自动化测试框架之控制界面的关键
- 用Flash控制vfp程序,疯狂扩展您的程序功能和界面
- 利用windows timer控制界面换颜色
- tomcat(一):一次解决tomcat9无法登陆控制界面的经历
- 通过Qt界面控制步进电机的启停
- 功率控制(CDMA关键技术)
- Introscope 7为关键任务应用提供有效控制
- 在Access中利用Jquery技术实现专业的界面和权限控制的通用程序
- 控制界面控件的遍历顺序
- 控制台窗口界面控制设计
- Android 应用程序中的界面控件与程序控制
- C#制作Windows service服务系列三--制作可控制界面的Windows服务(windows service)
- 2014——SDN控制平面的关键一年
- 控制台窗口界面控制设计(一)
- 用Flash控制vfp程序,疯狂扩展您的程序功能和界面
- 我的ios做的,酒店平板灯光空调控制界面