3.2 HTML DOM测试应用
阶段要点
● DOM的简单介绍。
● DOM在QTP中使用的时机。
● DOM对象与IE对象模型的结合应用。
● DOM在Web测试中的具体应用。
● DOM在Web测试中的显著优势。
3.2.1 了解DOM在QTP中应用的好处
3.2.1.1 什么是DOM
DOM全称为“Document Object Model”,从字面上来看叫做“文档对象模型”。它是一款主要应用于Web HTML中的一种独立的语言。在如今的网络时代,DOM一直被广泛应用着,基本上在任何地方都能够看到它的身影,随意打开一个网页的源代码就能找到。HTML DOM主要通过定义一套标准的对象通道接口,使得我们能够轻松地访问并控制HTML对象元素,它是一种用于HTML和XML文档的编程接口。作为开发人员可以通过DOM非常方便地控制文档对象中的属性、方法和事件。DOM的表现方法是一种树形结构。所有网页中最外层的元素都是<html></html>,称作DOM的顶层元素,里面还会有很多的子元素,这些元素都会把它视作为一个个节点,也就是node。通过Document对象就可以操控整个文档中的所有节点对象。下面是一段最简单的Dom应用脚本:
<html> <head> <script language = "vbscript"> Function helloworld document.write "test" End Function </script> </head> <body> <input type = "button" value = "click it" onclick = "helloworld"> </body> </html> |
在脚本中可以看到顶层元素为<html>,这个之前已经提过,接着就是头和身体两大元素,在body中可以看到一个子元素button,此元素含有一个点击事件,点击后即会触发script节点下的helloworld函数。此处函数中调用了document对象的write方法,当把以上代码保存为html文件后,点击button后即会执行helloworld方法,调用document.write,整个页面被写入test。那作为document这个可以操控整个文档对象的总入口究竟有哪些方法呢,让我们来看一下。
首先需要确保计算机里已经安装了Office。其次打开Office安装目录下的Office11\MSE7.EXE文件,此程序不管是对于DOM的查阅还是编写都是非常有帮助的。还有一个好处就是,不用另外安装其他软件,十分方便,接下来我们就来看一下它的威力。
新建一个HTML PAGE,输入上述代码,当想调用document对象的方法的时候,可以同时看到其他部分对象属性和方法,如图3-8所示。
图3-8
从图3-8所示可以看到此工具可以获取到document的部分属性和方法,以及进行代码提示,从而提高了开发人员编码的效率。由于很多工具都没有dom的提示,因此,在此处推荐这个Office附带的小工具。注意,为什么此处一直说是部分属性和方法,因为还有很多对象和方法被隐藏了起来,不过还是可以通过脚本定位跟踪法来查找其所有的方法。首先双击document对象,按下F1键后弹出document对象的帮助信息,如图3-9所示。
图3-9
如图3-9所示,选择All后就可以很方便地查看document下的所有方法属性事件了,并配有相应的语法说明和实例,非常的好用。讲了那么多DOM概念,接下来看一下DOM在QTP中应用的好处。
3.2.1.2 何时在QTP中使用DOM
在使用QTP测试Web页面时,首先需要加载Web插件,随后QTP就可以顺利地识别一些标准的控件,但有些时候网页中存在一些特殊控件或者存在大量的相同控件时,可以尝试使用DOM的方式来进行控制,因为QTP只对一些标准的控件支持比较好,而有些特殊的控件QTP无法识别,导致无法对其进行操作。DOM是一种最底层的对象操作模型,使用它来控制对象不但速度快,而且可以访问很多QTP本身无法访问的东西。接下来就来一一举例说明。
1.修改控件自身接口
此方法其实已经在第一章里详细讲解过它的应用,原理就是调用了DOM对象接口来修改控件的自身接口属性,这也是QTP本身所无法做到的。在实际测试过程也是一个非常有用的技术,关键时刻可以使问题迎刃而解。
2.DOM对象下CurrentStyle对象应用
CurrentStyle 是一个可以与HTML 对象元素的style sheets进行交互的接口,它可以获取对象元素的字体名、字体大小、颜色、是否可见等。在Web测试中真对一些特殊的界面验证点时能够发挥出很大的作用。在后续的章节中会详细对其进行分析讲解。
3.性能提升
对于性能来说,DOM的执行速度会比QTP的对象库执行速度快上好几倍,这是因为DOM相当于底层的对象接口,而QTP首先需要把对象属性进行封装,然后在脚本运行时调用对象库中的对象,最后与页面上的对象进行比对,如果属性匹配才可控制测试对象。而DOM却是直接找对象进行控制。所以,性能上相对于QTP的对象库有很大的提升,不过此优势一般只有在大量的相同对象或者一些特殊情况的时候才能有明显的区别,这个也会在后续章节详细进行讲解。
注意:使用DOM时也需要注意一点,虽然DOM有很多优势,但是也不要过分依赖DOM,对象库才是QTP的核心,过分使用DOM会导致脚本维护方面相对比较繁琐,毕竟对象库维护起来是最方便的,否则Mercury也不用花费那么大的劲来开发对象库了,而且对于不熟悉DOM的自动化测试工程师来说,会增加他们的负担,所以在使用时也请注意这些细节问题。
3.2.2 IE对象模型结合HTML DOM的Web应用
许多Web应用程序都是基于IE来开发,包括现在很多安全控件,密码控件等大多都只支持IE浏览器,以及使用QTP来对Web测试对象进行操作时也基本上使用的是IE,虽然QTP现在最新的版本开始慢慢支持其他浏览器,但被测系统大多还是基于IE来测试的。因此,熟悉IE自动化模型成了学习Web自动化测试的一项重要任务。接下来看一下具体如何操作。
1.启动IE(3种常见方法)
(1)在QTP中启动IE:
'在QTP中启动IE systemutil.run "iexplore.exe" |
(2)使用WSH启动IE:
'使用WSH启动IE Set oShell = CreateObject("wscript.shell") |
(3)使用IE COM对象:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL |
小技巧:使用此方法还可以获取窗口的句柄,并通过QTP来定位浏览器,代码如下:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '获取窗口句柄 ieHwnd=oIE.HWND '通过句柄定位浏览器并关闭 Browser("hwnd:= " & ieHwnd).Close |
2.等待页面加载
可以使用IE COM的Busy属性来确认浏览器是否处于加载状态。并为后续的操作做铺垫,若是没有此步骤,后续的一系列操作可能会无效。因为,当IE浏览器还没有加载完成时,对Web测试对象进行操作可能会出现无效的情况。因此,为了测试的顺利进行,需要在脚本中加入页面等待来保证后续的操作步骤顺利进行。
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend |
接下来对比一下页面加载和没有加载的区别。
(1)添加页面加载等待脚本,最后一步oIE.Document.f.wd.value = "zzxxbb112"先不用管,会在后面的内容中讲解:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend '百度搜索框输入 oIE.Document.f.wd.value = "zzxxbb112" |
结果:执行成功,打开IE浏览器后,成功输入zzxxbb112,如图3-10所示。
图3-10
(2)不添加页面加载等待的脚本,去掉While oIE.Busy: Wend这步:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 'While oIE.Busy: Wend '百度搜索框输入 oIE.Document.f.wd.value = "zzxxbb112" |
结果:执行出错,报出“缺少oIE.document对象”的错误信息,如图3-11所示。
图3-11
原因分析:由于IE浏览器跳转url后需要一定的加载时间,如果在还没有加载页面时,就直接使用document对象是不可以的,必须等待加载完毕,才能够对document对象进行操作,因此,程序会抛出一个缺少对象的异常。
3.遍历所有IE浏览器窗口
可以使用Windows的SHELL.Application遍历所有打开的IE浏览器窗口,并在所有打开的窗口中判断其窗口是否为IE浏览器窗口后存入字典对象集合中。在这里写一个遍历所有IE浏览器窗口并且返回一个字典对象集合的Function函数。
'遍历所有IE对象 Function EnumerateIE() On Error Resume Next '创建一个字典对象并返回所有当前打开的IE集合 Set EnumerateIE = CreateObject("Scripting.Dictionary") '获取所有Windows窗口 Set oWinShell = CreateObject("Shell.Application") Set allWindows = oWinShell.Windows '遍历每个Windows窗口 For Each oWindow In allWindows '检查如果是IE就添加字典对象中 If InStr(1, oWindow.FullName, "iexplore.exe",vbTextCompare) Then EnumerateIE.Add oWindow.hwnd, oWindow End if Next End Function |
接着就可以对此函数进行应用了,例如,关闭所有IE窗口:
'获取所有IE窗口对象的列表 Set allIE = EnumerateIE() '关闭所有打开的IE窗口 For Each oIE In allIE.Items oIE.quit Next |
结果:通过调用刚才写的函数,成功关闭所有打开的IE窗口。同样的效果,如果在QTP中只需要一行代码就可以完成,代码如下:
SystemUtil.CloseProcessByName ("iexplore.exe") |
4.利用DOM操作测试对象
现在已经会使用IE COM组件来对IE浏览器进行自动化的操作,但是对于浏览器页面中的测试对象IE COM是无法对其进行操作的,这个时候就需要使用HTML DOM来对其进行操作。HTML DOM是HTML Document Object Model(文档对象模型)的缩写,它将网页中的各个元素都看作一个个对象,从而使网页中的元素也可以被计算机语言获取或者编辑。 接下来看几个简单的例子。
3种方法对比:getElementByID、getElementsByName、getElementsByTagName。
(1)通过getElementByID方法获取定位对象,并对其进行操作:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend '获取Document对象 Set oDoc = oIE.Document '使用DOM对测试对象进行操作 With oDoc '搜索框输入 .getElementByID("kw").value = "zzxxbb112" '点击百度搜索 .getElementByID("sb").Click End With Set oDoc = Nothing Set oIE = Nothing |
结果:运行后首先是打开浏览器跳转百度首页,等待加载完成之后,创建DOM对象,并使用getElementByID获取百度搜索框对象,并对其进行输入“zzxxbb112”后,再次通过getElementByID方法获取百度搜索按钮并进行点击,最终成功跳转搜索结果。
(2)通过getElementsByName方法获取定位对象,并对其进行操作:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend '获取Document对象 Set oDoc = oIE.Document '获取元素名为WD的集合 Set oEdits = oDoc.getElementsByName("wd") '遍历对象并对其进行操作 For Each oEdit In oEdits oEdit.value = "zzxxbb112" Next '点击百度搜索 oDoc.getElementByID("sb").Click Set oDoc = Nothing Set oIE = Nothing |
结果:使用getElementsByName和getElementByID不同,getElementByID是返回的单个对象,而getElementsByName返回的是一个元素的集合,需要通过遍历对象才能对其进行操作。
(3)通过getElementsByTagName方法获取定位对象,并对其进行操作:
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend '获取Document对象 Set oDoc = oIE.Document '获取TAG名为INPUT的元素集合 Set oEdits = oDoc.getElementsByTagName("INPUT") '遍历对象并判断文本框对其进行操作 For Each oEdit In oEdits If oEdit.type="text" Then oEdit.value = "zzxxbb112" End If Next '点击百度搜索 oDoc.getElementByID("sb").Click Set oDoc = Nothing Set oIE = Nothing |
结果:使用getElementsByTagName获取TAG名,通过得到相同类型的元素及在遍历中进行判断控件类型并进行操作。
5.利用FORM名来获取对象元素
如果使用FORM名来获取对象元素会大大简化我们的脚本。首先用IE DEV查看百度的搜索框对应的FORM名,在IE DEV中查看得到FORM名为f,如图3-12所示。
图3-12
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend '获取Document对象 Set oDoc = oIE.Document '获取FORM名为F下名为WD的元素并输入 oDoc.f.wd.value = "zzxxbb112" '获取FORM名为F下名为SB的元素并点击 oDoc.f.sb.Click Set oDoc = Nothing Set oIE = Nothing |
结果:通过以上脚本可以看到代码非常简单,同样可以达到相同的效果。
6.访问Web页面的Script脚本变量
通过DOM可以直接访问Web页面中的JavaScript或者VBScript中的变量。
首先打开百度的源文件,如图3-13所示。
图3-13
可以看到,在百度源文件中的JavaScript脚本中定义了一个变量为W,并且赋值为document.f.wd,从上面的例子可以很明显地知道,此处的W代表的就是百度搜索框这个对象,那么就可以直接操控W这个对象来对百度文本搜索框进行自动测试。
'使用IE COM启动IE Set oIE = CreateObject("InternetExplorer.Application") oIE.Visible = True '设置可见 oIE.Navigate "http://www.baidu.com" '跳转URL '等待IE页面加载完毕 While oIE.Busy: Wend '获取Document对象 Set oDoc = oIE.Document '获取百度搜索框对象 Set oEdit=oDoc.parentWindow.w '并对其进行输入 oEdit.value = "zzxxbb112" '获取FORM名为F下名为SB的元素并点击 oDoc.f.sb.Cclick Set oDoc = Nothing Set oIE = Nothing |
从以上代码可以看到,只需要通过parentWindow来访问Web页面Script中的变量即可。
7.总结
这一章主要介绍了利用IE的COM以及HTML DOM来自动化IE浏览器,以及对浏览器的一些控件对象进行自动化的操作,包括启动IE、等待页面加载、遍历所有IE窗口、利用DOM操作测试对象、利用FORM名来获取对象元素、访问Web页面的Script脚本变量、Browser对象转化Window窗口对象、自定义浏览器应用程序,这些方法对于我们在自动化测试中也是起到比较重要的作用,并且能够辅助我们更好地完成Web自动化测试,当QTP不能达到我们想要达到的目的时,就可以使用这些方法来代替或者说来实现需要实现的方法,最终使Web自动化测试变得更加的轻松和容易。