51Testing软件测试论坛

标题: QTP11中EmbedScript 和 RunScript 的区别 [打印本页]

作者: lsekfe    时间: 2012-11-14 11:55
标题: QTP11中EmbedScript 和 RunScript 的区别
问起QTP11中多了的两个方法EmbedScript. 和 RunScript的区别。
这里先介绍语法形式为 :Browser("Browser").EmbedScript. / Browser("Browser").EmbedScriptFromFile
Browser("Browser").Page("Page").RunScript. / Browser("Browser").Page("Page").RunScriptFromFile

那么它们有什么区别呢?

先说共同点。共同点是它们都是调用JavaScript

具体可以参考另一篇博文《QTPWeb页面上的文本框赋值的技术大全》.

假如要在百度首页的输入框赋值,可以调用JS代码。

代码1:

1 SystemUtil.Run "C:\Program Files\Internet Explorer\iexplore.exe"
2 Browser("Browser").Page("Page").Sync
3 Browser("Browser").Navigate "http://www.baidu.com/"
4 Browser("Browser").Page("Page").RunScript"document.getElementById('kw').value = '51testing'"

代码2:

1 SystemUtil.Run "C:\Program Files\Internet Explorer\iexplore.exe"
2 Browser("Browser").Page("Page").Sync
3 Browser("Browser").Navigate "http://www.baidu.com/"
4 Browser("Browser").Page("Page").Sync
5 Browser("Browser").EmbedScript"document.getElementById('kw').value = '51testing'"


运行后,效果是不是一样的?

但是请注意,代码2的EmbedScript代码行上面多了一句:Browser("Browser").Page("Page").Sync

为什么要这样呢?接下来,请去掉这段代码,运行QTP,看到什么了?

哦,你会发现有时候QTP运行的结果跟代码1还是一样的,但是有时候运行的结果报错,提示信息是:

网页错误详细信息


用户代理: Mozilla/4.0 (compatible; MSIE 8.0;
Windows
NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)

时间戳: Thu, 8 Nov 2012 03:31:38 UTC




消息:'document.getElementById(...)' 为空或不是对象
行: 1
字符: 1
代码: 0
URI: http://www.baidu.com/
还有些时候,你会发现浏览器瞬间闪过一个黄色的惊叹号(就是报错信息),然后立即刷出了百度首页——只不过这次搜索输入框中并未正确的输入“51testing”的字符串。

换句话说,你使用EmbedScript不加Browser("Browser").Page("Page").Sync的结果就是代码运行非常不稳定。

这又是怎么回事呢?

先弄清楚Sync是干什么用的。Sync事实上是网页中的同步点,指的是QTP会等待整个web页面完全加载完成后(在IE浏览器左下方能看到“完成”的字样),再执行下一步代码。通常情况下QTP在做Browser("Browser").Navigate动作之前会自动帮你做一次等待,这个是因为有些人的浏览器默认会打开一个网页,比如是 hao123、hao.360.cn、123.sogou.com这种导航页,QTP会等你把这个页面刷完之后再做Navigate,因此我建议大家平时使用“about blank:”会加快你QTP的回放速度。

好,绕了个弯。现在来说为什么“代码1”不需要,而“代码2”需要。

因为:

RunScript是在Page对象里运行一个指定的脚本,当执行到Browser("Browser").Page("Page").RunScript行这段话时,QTP会试图先识别Browser对象再识别Page对象(如果大家听过我的QTP课的对象识别原理的录制原理和回放原理,这里就会轻松过关),当它试图RunScript的时候,必须先等待Page对象出现!而QTP如果没有等到Page对象会进入“全局同步等待”(File-Settings-Run-"Object synchronization timeout"的设置),只要没有timeout,它就会进行等待。也就是等百度的首页出现了,才去RunScript。

而“代码2”中,是Browser("Browser").EmbedScript这段话。请注意这里没有Page对象!而Browser对象老早就已经加载进来了(第2行就已经加载完毕了),所以这个时候QTP并没有进行“全局同步等待”,而是“瞬间”去执行下一行代码:

Browser("Browser").EmbedScript。问题是现在百度的首页Page对象都还没有加载进来(DOM对象也没有加载进来),你就直接运行document.getElementById怎么可能成功呢?皮之不存,毛将焉附?


再来看更加本质的区别。

EmbedScript的作用是 Runs the specified JavaScript. each time a page or frame. loads or refreshes in the browser. 也就是在你每次加载这个Page页面或者frame框架的时候都会运行它,并且注意:


什么意思?就是只要没有关闭浏览器或者运行的会话还在,这段脚本一直生效!

再强调一遍:RunScript只是运行脚本(一次性的),一旦页面被重新载入(比如再触发一次Navigate),脚本的生存期就结束了;而EmbedScript则是相当于加载一个脚本(常驻的),即使页面发生跳转、重新载入也仍然有效。再来看下面两段代码的对比。

代码3:

SystemUtil.Run "C:\Program Files\Internet Explorer\iexplore.exe"
Browser("Browser").Page("Page").Sync
Browser("Browser").Navigate "http://www.baidu.com/"
Browser("Browser").Page("Page").Sync
Browser("Browser").Page("Page").RunScript. "var i;i=0;i++;i++;"
Browser("Browser").Page("Page").Sync
Browser("Browser").Navigate "http://www.baidu.com/"
Browser("Browser").Page("Page").RunScript. "alert(i);"


运行后,会报错:

A JavaScript. error occurred in "alert(i);":
'i' 未定义.


代码4:

SystemUtil.Run "C:\Program Files\Internet Explorer\iexplore.exe"
Browser("Browser").Page("Page").Sync
Browser("Browser").Navigate "http://www.baidu.com/"
Browser("Browser").Page("Page").Sync
Browser("Browser").EmbedScript. "var i;i=0;i++;i++;"
Browser("Browser").Page("Page").Sync
Browser("Browser").Navigate "http://www.baidu.com/"
Browser("Browser").Page("Page").RunScript. "alert(i);"


代码运行后,百度页面会弹出一个对话框,显示i的值为2.


怎么样,看出区别了吗?

好,那接下来讲应用。通常,我们会习惯上把EmbedScript和RunScript结合起来使用。先用EmbedScript加载一个js文件,比如jQuery的js脚本,然后用RunScript去运行某个方法。比如这种用法:


Browser(":=").EmbedScriptFromFile"c:\jquery-1.3.2.js"
str = "EmbedScript. QTP"
Browser(":=").Page(":=").WebEdit("name:=wd","type:=text").Set str
Browser(":=").Page(":=").WebButton("name:=OK","type:=submit").Click
iCount = Browser(":=").Page(":=").RunScript("$('#resultStats').children('b').eq(2).text()")
lPage = CLng(iCount) - 10
Browser(":=").Navigate "http://www.songfun.com/search?hl=en&q=" & str & "&start=" & lPage & "&filter=0"

作者: 赵佳乐SMILE    时间: 2012-11-14 16:27
虽然看不懂 但感觉写的很好

楼主你换头像了
作者: 黑羽祭    时间: 2012-11-14 16:49
顶上~~
这个没留意过,有时间要好好学习一下
作者: xjwldlover    时间: 2012-11-23 15:35
好文~!收藏了
作者: xjwldlover    时间: 2012-11-23 15:42
不测试基于组件的web应用无法体会到这两个函数的绝大妙用啊,怎一个爽字了得~




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2