Rational® Performance Tester(以下简称 RPT)是 IBM 基于 Eclipse 平台的性能测试解决方案,为测试人员提供了一整套性能测试功能,包括测试脚本录制、测试场景规划、测试结果分析等。本文主要介绍如何将其测试脚本录制功能运用于 Web2.0 网站。
为了更好地理解 RPT 脚本录制过程,这里简单介绍一下 RPT 脚本录制的基本原理:RPT 在录制脚本之前首先配置网络浏览器(如 IE、FireFox,由测试人员选择)使用代理服务器(localhost)和特定端口(默认是 1080),然后启动新的浏览器窗口,测试人员通过该窗口访问被测试的网站,RPT 在后台通过监听和分析进出特定端口的网络数据包来获取测试人员的请求和网站的响应内容。在测试人员关闭浏览器窗口之后,RPT 完成监听,将收集到的网络数据分别解析,通过 Java 代码调用这些 http 请求和响应。
![]() ![]() |
![]()
|
在之前的 Web1.0 环境中,用户通过浏览器获取信息,而 Web2.0 则更注重与用户的交互作用,用户既是网站内容的消费者,也是网站内容的创造者。如今,网站用户从过去的单纯被动的“接受”变成了现在多元化的主动创造。目前 Web2.0 技术主要包括:博客(BLOG)、RSS、百科全书 (Wiki)、社会网络(SNS)等。
Web2.0 网站基于 Web2.0 的理念,给用户以“主人翁”的感觉,通过 Ajax 等技术提供丰富的用户体验,赋予用户更大的操作空间。在这些优点的背后,网站使用了大量的网页后台交互技术,使得网页已经不再是过去简单的静态页面,变成了频繁与后台服务器交互信息并提供美观显示的前端。
针对 Web2.0 网站的特点,在测试此类网站时,主要存在以下几个难点:
- 如何监控网页各个部分的加载状态,由于 Web2.0 网站通常采用异步通信模式,一个简单的鼠标点击就可能导致大量的网络通信。
- 如何处理数据关联,在测试脚本录制完毕之后,测试人员需要手动做一些前后 http 请求和响应内容的关联。对于 Web2.0 网站来说,一个 http 请求包含的 post 数据量可能高达 10K,如何在这种大容量的网络数据中实现数据关联需要认真研究。
- 如何同时模拟多种类型用户的行为。
- 如何从动态 http 响应内容中获取合理数据提供给后续 http 请求。
![]() ![]() |
![]()
|
RPT 支持测试人员根据自己的业务需要,选择合适的网络浏览器录制测试脚本。配置特定浏览器的属性位置是:菜单 ->Windows->Preferences->Test->Http Record,设置浏览器应用程序的路径和代理端口。在本文前面中提到 Web2.0 网站的一个显著特点是网页包含很多的动态元素,而这些元素往往都是通过底层的 Ajax 技术与服务器端进行交互,这就要求测试人员在录制脚本时要对当前测试网页的状态和运行过程了如指掌才能产生符合业务需求的脚本。例如在网页中一些动态预览功能、动态加载和删除功能,如果不能监视这些网络通信,只是盲目的点击鼠标,则录制的脚本很可能包含错误的或者多余的 Http 请求。因此,作者推荐在录制 Web2.0 网站测试脚本时使用 FireFox 浏览器和 FireBug 插件,相信大家对这些都不陌生,选择的关键理由就是开源的 FireFox 浏览器可以提供众多的适用于开发和测试的插件,这其中就包括 FireBug 插件,这款插件允许 FireFox 用户在浏览网页时实时的查看当前网络浏览器的请求和响应,非常适合测试人员在录制脚本时使用。
在开始录制测试脚本之前,需要清理浏览器缓存数据。Web2.0 网站为了提供舒适的用户体验,通常使用了大量的 javascript、css 文件和 cookie 机制。测试人员在录制脚本之前都会首先使用浏览器手动操作一遍测试场景,确认网站可以正常运转后,才开始正式录制。此时,网络浏览器(如 FireFox)就会将 .html、.js、.css 文件等缓存到本地硬盘中,cookie 文件也设置完毕。如果不删除这些缓存数据,那么 RPT 在录制脚本时,浏览器针对某些 http 请求就会使用缓存的文件,导致脚本录制的行为与初始测试场景不一致。因此,清理浏览器缓存数据(包括 cookie)是录制成功的重要一步。
![]() ![]() |
![]()
|
在点击“录制”按钮之后,RPT 会配置浏览器代理,然后启动浏览器。测试人员在地址栏填入测试网站的 URL,回车。此时,整个脚本录制过程正式开始。由于 Web2.0 网站通常具有丰富的网页元素,其加载时间要比普通的网站长,导致测试人员在使用 RPT 录制脚本时误以为页面已经加载完毕(表面上是这样),随即开始了下一个测试动作,造成之前的 Http 请求还没得到完全响应,又开始了新的请求。这种情况在某些 Web2.0 网站中会出现,RPT 在录制时会抓取一些前后顺序颠倒的 Http 请求,为后面的脚本调试工作带来了很大麻烦。所以,为了更好地监控网站加载状态,请打开 FireBug 插件,如图 1 所示,它可以实时显示当前页面的加载情况。测试人员只有在确信当前动作的所有 Http 请求得到响应之后,再进行下一个动作,保证测试脚本顺序的正确性。
图 1. FireBug 监控网站加载状态
![FireBug 监控网站加载状态](https://i-blog.csdnimg.cn/blog_migrate/4182d86cc01e16affe0735a31894d6f4.png)
Web2.0 网站的一个显著特点是动态元素很多。例如,用户将鼠标移动到某个城市名字的超链接上,网页某处可以自动显示出该城市的交通图。这就要求测试人员在录制脚本时,控制鼠标的移动轨迹,有针对性的将鼠标移动到需要测试的页面元素上,让 RPT 录制到正确的脚本。作者曾经遇到过类似情况,在网页上把鼠标移动到某个文件名时,底层 JavaScript 将文件名字发送给服务器,服务器生成该文件的快照返回给浏览器并显示在页面上,当我的鼠标不经意间划过若干行文件列表时,RPT 已经录制了大量的 Http 交互动作。正确的做法是,确定哪些动态元素在测试范围之内,然后控制鼠标移动轨迹,采用 FireBug 监测底层网络通信过程。
RPT 在进行性能测试时可以模拟 cookie,也就是说 RPT 在发出 Http 请求后会根据 Http 响应正确的设置 cookie。RPT 的这个优点也要求测试人员应该录制用户完整的状态。某些 Web 2.0 网站利用 cookie 保存用户的登陆状态等有效信息,这些信息会随着用户登出而删除。测试人员在录制带有用户状态的测试脚本时最好包括完整的用户登陆、注销过程,避免 cookie 中留下错误的状态信息。RPT 在模拟多个用户操作时,针对每一个用户流(例如,测试人员选择 RPT 模拟 40 个用户,数据池为 1000 个用户,则 RPT 会生成 40 个用户流同时执行脚本,每一个用户流会从数据池里选取一个用户,执行脚本后继续下一个用户)会维护一个 cookie 池,同一个用户流的用户会共用同一个网站的 cookie,如果脚本没有录制用户完整状态(例如,缺少用户注销步骤),前一个用户运行完脚本后,cookie 可能还保留着登陆状态,下一个用户在登陆时就会直接转到欢迎界面,后面的 http 请求(例如发送用户名和密码)就会发生响应错误。因此,对于有状态的测试场景,录制用户完整状态是很重要的。
对于例外情况,RPT 也做了特殊的支持。例如,作者曾经遇到过一个用户调查场景。用户在浏览器中输入调查表的 URL,网站自动转到登陆界面,输入用户名和密码后,回车,网页重定向到调查表页面,该页面只有调查,没有注销链接。在这种情况下可以使用 RPT 设置脚本的 Http 选项,双击录制的测试脚本,在“HTTP Options”中,选中清除 cookie,如图 2 所示:
图 2. 清除 cookie
![清除 cookie](https://i-blog.csdnimg.cn/blog_migrate/f7e45a58cdab7441fbc2d478de15933f.png)
在选中该选项后,每次用户流开始一个新的用户之前,都会清除 cookie,不会保留任何用户状态,从而方便后面脚本的执行。
![]() ![]() |
![]()
|
RPT 在录制测试脚本完后,会显示所有 http 请求和相应的响应。对于一个典型的 Web 2.0 网站脚本,你可以看到其中的 js、css、图片文件请求的数量远多于有效业务逻辑请求,甚至是 2 个数量级的差距,这是由 Web 2.0 丰富的用户体验决定的。这些文件虽然不大,但是数量众多,每一个文件代表一个 Http 请求,对服务器的压力占有重要地位。如何处理这些非业务请求,需要根据网站的业务需求来分析。如果网站的性能规格说明要求对于固定数量的新用户提供长期运行支持,则保留这些请求,否则删除,因为对于频繁登陆网站的用户来说,Web 浏览器会缓存这些文件,也就不会对服务器造成压力。
在录制测试脚本时,RPT 会根据用户的停顿时间和页面转换等因素对录制的请求进行分页。分页功能可以方便测试人员设置 think time、查看 response time。由于测试人员在录制 Web2.0 网站脚本时停顿间隔不好量化,所以在录制完毕之后要重新调整分页。分页的基本原则是:以一个主 http 业务请求为分页界限,加上其他非业务请求(如果保留的话),该主业务请求应该能够实现一个比较完整的用户动作,比如填写一个控件、提交等。因此,对于元素稠密的页面,要使用分割功能:选中某 request,右键选择“Split Page Here...”;对于元素稀疏的页面,要使用合并功能:选中多个需要合并的页面,右键选择“Merge Pages...”,分页的标准取决于网站的实际商业需求。
在录制完脚本之后,RPT 会自动做一些数据关联,即把一些特定于 session 的响应数据(例如,显示以当前登陆用户名命名的文件夹)关联到正确的数据池或者之前的 http 请求中,保证脚本在运行时不出错。Web2.0 网站的 http 请求通常复杂众多,所以一个良好的调试方法显得很重要。这里可以利用 RPT 的单脚本运行回放功能验证脚本的正确性。具体步骤是,在 Test Navigator 选中测试脚本,右键选择“Run As Performance Test”。该功能允许脚本单独运行,在版本 7.0.2 之后,你可以一边运行脚本,一边通过 RPT 动态查看服务器返回的 http 响应页面。在运行完毕之后,可以通过结果分析具体的脚本细节。步骤如下:在 Test Navigator 选中单遍测试结果,右键选择“Display Test Log”。主要查看两部分内容,一个是 http 响应是否正确,一个是数据关联是否合理,如果数据关联发生错误,RPT 会以 message 的方式提醒测试人员,利用 message 可以定位到具体的 http 请求和关联处。举例来说,如果出现 message,就说明对应的 http 响应出现了问题,即不能从中抽取要关联的数据,或者此处就不应该抽取关联,而可能需要在更早之前的请求中抽取,测试人员应该仔细分析各种可能性。
RPT 一方面可以为测试人员录制的脚本自动实现数据关联,另一方面也允许测试人员手动实现某些遗漏或错误的关联。这里,作者针对 Web 2.0 网站的特性,总结了一些查找替换技巧:
- 充分利用 Test Search 功能,通过在前面介绍的单脚本运行回放功能可以确定数据关联失败的 http 请求位置,然后根据其响应提供的错误信息,分析出错的原因。比如,请求中的一个 ID 号没有关联或者关联失败,然后使用该 ID 号进行 Test Search,通过这种方式可以找出在整个脚本中该 ID 号出现的所有位置。
- 通常情况下,http 请求被关联的数据来自之前最近的一个 http 响应内容。但是对于 Web2.0 网站来说,某些 http 请求内容太大(post data 可能超过 100K),从这样大数据量的字符串中采用正则表达式抽取关联的数据可能会失败,所以比较稳健的方法是把某些数据关联到最早出现的一些 http 响应内容上。
![]() ![]() |
![]()
|
RPT 提供数据池关联功能,允许测试人员设定某些测试脚本中的数据取自一个含有若干元素的数据池。Web 2.0 网站存在许多可能需要数据池的地方,比如登陆的用户、选中购买的商品、调查表中填写的内容等等。RPT 为了应对各种不同的测试需求,提供了对数据池配置的多种选择,比如测试人员可以利用 RPT 提供的时间序列数作为数据池(模拟一些随机不可重复的文件名等),也可以手动建立数据池(模拟用户名、密码)。
Web 2.0 网站通常为各种用户提供了访问的内容,从不同角度可以分很多种,比如注册用户、非注册用户,浏览用户、操作用户,直接访问用户、程序访问用户,等等。为了更好地模拟这些用户在实际商业场景中的运行情况,RPT 允许测试人员根据产品需求规格说明,同时执行多个脚本模拟用户分布。基本的步骤是,比如要模拟注册用户和非注册用户的比例 7:3,则在 Test schedule 中,加入两个脚本,其中一个为注册用户所有(包括了登陆过程),另一个测试匿名访问脚本,然后设置用户比例,效果如图 3 所示:
图 3. 模拟网站用户分布
![模拟网站用户分布](https://i-blog.csdnimg.cn/blog_migrate/1ef413d7aaaa3a062b78b5074e10e69f.png)
Web 2.0 网站其主要的特点是动态性,比如对于一个在线书店,当用户在选中一个图书分类时,网页会把该分类对应的所有图书列出来,然后用户通过点击某些链接来购买相应的图书。为了使测试更真实地模拟用户操作,测试脚本需要自动判断该分类下是否存在图书(即判断 http 响应内容是否包含有效链接),以及在图书存在的情况下随机选择一本书的超链接来模拟购买操作,RPT 允许测试人员通过编写代码来提供这些合理的数据。具体的步骤是,将点击分类之后返回的 http 响应内容作为一个 field reference,然后插入一个 custom code,输入参数就是刚才的 field reference,定制代码如下:
清单 1. 定制代码抽取合理数据
public String exec(ITestExecutionServices tes, String[] args) { String source = args[0]; String returnValue = null; /* 处理输入参数字符串 source,解析出全部的有效超链接, 随机选择一个,然后赋值给返回值字符串 resturnValue */ return returnValue; } |
请注意该函数返回值是一个随机抽取出来的超链接,这样在后面的 http 请求中,可以把此 custom code 的返回值关联到 RPT 录制的超链接上,从而可以模拟用户随机选购图书。
![]() ![]() |
![]()
|
在录制、调试和配置完测试脚本之后,下一步就是建立测试场景,包括设置用户数、测试时间、资源监控等,具体说明参见 RPT 帮助文档,这里只列出 RPT 适合 Web2.0 网站测试的一些特性:
- 可以设置不同的用户组,每个用户组运行不同的测试脚本,在前面已经提到。
- 既可以设置脚本运行次数,也可以设置脚本运行时间。
- 可以设置模拟用户添加的间隔时间。
监控资源在 Web 性能测试中扮演关键的角色。如果 Web 2.0 网站运行在 Windows 2003 Server 等 Windows 服务器上,RPT 支持通过远程 Perfmon 工具直接在 RPT 本机上查看被测试服务器的系统资源;而对于非 Windows 平台(Linux,Soalris,AIX),RPT 也允许通过在远程服务器上安装监控客户端,然后从本地查看资源使用情况。
![]() ![]() |
![]()
|
本文主要讲述了如何使用 Rational Performance Tester 录制、调试和配置基于 Web2.0 网站的测试脚本,包括一些作者的经验分享。