简介
随着越来越多的企业应用被移植到Web上,Web应用正变得日益复杂。它们被用来实现复杂的业务流程例如交易甚至工作流。一个业务流程通常包含若干步骤。这些步骤间自然地需要共享某些数据以完成一次连续的“计算”。例如,某一个步骤的输出可能是下一个步骤所需的输入。在一个典型的Web应用实现中,业务流程的每个步骤对应为一个HTML页面,因而最终用户将与一系列连续的页面依次交互以完成一个完整的业务流程。由于Web的无状态特性,这些页面中通常需要存储一些信息来实现它们之间所需的数据共享,例如下一个页面的URL以及其他可能的输入参数等。这些信息常常是由服务器动态生成,因此每次的值都可能不同。但是,当Robot录制一个HTTP会话时,它只能记录这些数据在这个会话中的一个快照。尽管Robot采用了一种称为“动态数据关联”(Dynamic data correlation)的技术使得它能够关联部分动态的值,但还是无法找出所有需要关联的值并据此产生具备完善功能和足够灵活性的VU脚本。即使Robot可以简单地认为所有的数据都是动态的,如何在可用的HTML页面中抽取甚至构造这些数据的值则是一个更加复杂和困难的问题,因为Robot对这些数据后隐含的逻辑一无所知。因此,在Robot不能产生令人满意的VU脚本时,就需要手工修改进行完善。
下面将首先对Web应用中的数据关联作更进一步的剖析,接着介绍如何使用Robot的“动态数据关联”技术,然后详细讨论当Robot不能产生满意的脚本时一些可能的解决方案,包括动态数据值的定制抽取和客户端数据构造的模拟等。
Web应用中数据关联的分析
在Web应用中,当一个特定的HTML页面的URL或者个别输入参数的值是动态产生因而必须从先于它返回的页面包含的数据中抽取或者构造出来时,就发生了数据关联。动态输入参数的一个很好的例子就是当前很普遍的“Session ID”,它由服务器生成并返回给用户的浏览器,在访问下一个页面时这个ID需要被发送回去以获取存储在服务器端的会话上下文。输入参数通常以四种方式提交:HTTP头参数、Cookie、URL参数和FORM参数。由于URL参数可被认为是URL的一部分,因此可以认为有四种可能发生关联的动态数据:HTTP头参数、Cookie、URL、FORM参数。在Robot的VU语言中,一个HTTP请求是通过调用库函数“http_request”发出的,列表1是给出了一个典型的用例。请注意列表1中各粗体部分,它们分别代表了四种可能发生关联的动态数据的形式中的一种。
列表1. 函数http_request的典型用例http_request ["t3079"] "POST /pkmslogin.form HTTP/1.1\r\n" "Accept: image/gif, image/x-xbitmap, image/jpeg, |
正确处理数据关联的第一步是使用变量替换Robot录制的脚本中包含的动态数据的静态值,这些变量将在脚本运行时被动态地赋值。以列表1中的HTTP头参数“Referer”和FORM参数“login-form-type”为例,它们都由一个变量来赋值。但接下来的难题是:如何得到这些变量的值?一般有两种可能:一种是它们的值被直接包含在返回的HTTP响应中(包括响应的头和HTML内容)因而可以通过字符串抽取获得;另一种则需要进一步在抽取得到的若干值的基础上进行构造来获得。Robot能够自动地识别并抽取某些类型的动态值,这将在下一节中进行介绍。然而,目前它还不能发现所有这些动态值,更不用说根据一个未知的逻辑去构造一个值。因此,通常需要测试开发人员通过对VU脚本进行编程来定制变量值的抽取过程或者模拟某个数据构造过程。
这里需要澄清的是,动态数据和需要使用数据池(Datapool)的数据是不一样的。后者基本上是为了模仿最终用户的输入,它的值可以在脚本运行前确定并加载到数据池中(例如用户名和密码)。而本文中所指的动态数据大多是由服务器在运行时间生成和返回并需要在后续请求中以某种形式发送回去。不过,在某些非常特殊的情形下,例如当服务器对某个动态数据只生成一个有限集合的值(例如true和false)并且对用户会话不敏感,那么可以使用一个加载了所有这些可能值的数据池用于该动态数据的赋值,前提是能与服务器生成这些值类似的“逻辑”来从数据池中获得这些值(例如随机方式)。
使用Robot的“动态数据关联”功能
如前所述,关联的动态数据可以有四种形式提交给服务器,下面介绍Robot如何分别处理它们。
HTTP头参数
HTTP头参数产生关联的情形较其他几种形式少,但是有一个例外,即“Referer”头参数。根据HTTP协议,该参数的值应该指向上一个被访问的URL地址。由于URL的动态性,“Referer”成为一个非常普遍的需要进行关联的动态数据,因此Robot特别定义了一个名为“_reference_URI”的只读系统变量,用来存储上一个GET或者POST命令请求的完整URL地址。在其生成的脚本中,Robot会自动地用变量“_reference_URI”替换所有“Referer”头参数的值。

