ant: normal; text-transform: none; color: rgb(0, 128, 128); margin-top: 3px; ">测试自动化
图 2 屏幕快照中所示的 AJAX 应用程序测试工具系统由三个文件组成。图 4 显示了该工具整体结构的框图。工具本身(即 TestHarness.aspx)是包含两个框架的简单的网页。右侧框架包含待测试的 AJAX Web 应用程序。左侧框架包含测试方案页面,其中列出了一些最小 UI 和所有 JavaScript 代码,用于处理和检查待测试的 Web 应用程序。为保持一致,我打算将上述三个页面编写为 .aspx 文件,尽管这会使我无法将基本 HTML 用于测试工具和测试方案页面。下面是 TestHarness.aspx 页面的完整源代码:
<html> <head> <title>Test Harness for AJAX Web Apps</title> </head> <frameset cols="45%,*"> <frame src="http://localhost/AjaxTest/TestScenario001.aspx" name="leftFrame"> <frame src="http://localhost/AjaxApplication/Default.aspx" name="rightFrame"> </frameset> </html>
图 4 测试工具的结构 (单击该图像获得较大视图)
如您所见,主要的测试工具页面实际上就是一个容器文件。通过调用程序定义函数 asyncCall 开始运行测试方案,该函数会使待测试的应用程序向 Web 服务器发送异步 XMLHTTP 请求,同时调用程序定义的 delay 函数。该 delay 函数在 Web 服务器处理请求时进行循环,返回异步响应,并不时检查 Web 应用程序的状态。客户端收到响应且应用程序状态被更新后,delay 函数会发现网页的状态已发生改变,然后便可进行新的异步调用。
asyncCall 内部
AJAX 测试自动化技术的核心是一对程序定义函数,即 asyncCall 和 delay,用户应搭配使用这两个函数。asyncCall 方法如下:
function asyncCall(action, checkFunc, arg, callback, pollTime) { numTries = 0; action(); window.setTimeout("delay(" + checkFunc + ", " + "'" + arg + "'" + ", " + callback + ", " + pollTime + ")", pollTime); }
我传入了五个参数。第一个参数 action 是指向某例程的函数指针,该例程使用 Internet Explorer DOM 来触发操作,从而启动异步 XMLHTTP 请求。第二个参数 checkFunc 是指向某例程的函数指针,该例程在 Web 应用程序的状态表明异步响应已完成时返回 true。第三个参数 arg 是传递给 checkFunc 函数的参数。第四个参数 callback 是指向某例程的函数指针,系统会在异步响应已完成时调用该例程。最后一个参数 pollTime 用于指定合作伙伴 delay 函数中两次调用之间的等待时间(以毫秒为单位)。
在 asyncCall 函数内部,我首先将全局 numTries 计数器设置为 0。我使用该变量来跟踪进入 delay 函数的次数,以便在查找可表明异步响应已发生的尝试达到指定次数后能够退出。接下来,我调用 action 参数,该参数进而触发异步请求。请注意,附加到函数名的括号是用来调用函数的语法机制。
下面才是真正的技巧所在:我调用内部 window.setTimeout 函数。如您所见,setTimeout 接受两个参数。第一个参数是仅执行一次的 JavaScript 语句。第二个参数是在执行第一个参数前延迟的时间(以毫秒为单位)。如果检查 asyncCall 中的代码,您便会发现我传递给 setTimeout 的第一个参数变成了如下形式:
delay(checkFunc, 'arg', callback, pollTime)
第二个 arg 就是 pollTime。简言之,在 pollTime 毫秒的延迟后,我调用了程序定义的 delay 函数。
对 asyncCall 函数的调用如下所示:
asyncCall(clickNorth, imgIsTwo, "2", clickSouth, 200);
该调用可解释为“调用名为 clickNorth 的函数,然后进入 delay 循环,每隔 200 毫秒调用一次带有参数‘2’的函数 imgIsTwo,并在 imgIsTwo 最终返回 true 时,将控制权转至名为 clickSouth 的函数。”
在 asyncCall 方法的定义中,arg 周围的单引号字符非常重要。如果 asyncCall 定义中没有单引号,则参数将按引用进行传递,如下所示:
asyncCall(doThis, findX, "X", doThat, 200);
此类调用会生成错误,指出变量 X 未被定义。如果使用了单引号,则参数将按值进行传递。在本例中,您希望参数按值传递。
还有另一种有趣的方法可用来调用 asyncCall 内部的 window.setTimeout 函数。通常,您需要编写类似下列内容的代码:
window.setTimeout("delay(" + checkFunc + ", " + "'" + arg + "'" + ", " + callback + ", " + pollTime + ")", pollTime);
文章来源于领测软件测试网 https://www.ltesting.net/