尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LoadRunner性能测试脚本录制与开发:选对录制模式,掌握关联参数化

LoadRunner性能测试脚本录制与开发:选对录制模式,掌握关联参数化 简介一份面向软件测试初学者的完整实验报告围绕LoadRunner工具对飞机订票系统进行性能测试脚本录制与开发涵盖脚本录制HTML/URL两种方式、事务插入、参数化、集合点设置、自动关联及输出函数应用等核心环节。报告基于Windows7与UTF应用环境逐步展示了从启动服务、录制登录到综合订票流程的完整实践过程并配有大量界面截图、脚本代码和结果分析便于对照操作与理解原理。包内为1个doc文档体积6.2MB内容结构清晰包含实验目的、环境、步骤、结果和Action脚本示例可直接作为实验报告模板或复习参考。已有419人学习该资源说明其内容具有一定认可度。对于需完成软件测试性能测试实验的学生这份报告能显著提升脚本编写与调试效率帮助快速掌握LoadRunner关键功能。1. 性能测试脚本录制与开发先选对录制模式再谈脚本增强做性能测试时很多人把 LoadRunner 脚本录制理解成“按下 Record走一遍业务停止脚本就出来了”。实际踩过坑的都知道录制模式选错后面参数化、关联的事故会一块接一块回放时 session 丢失、登录失败、事务时间虚高甚至花一个下午在调一段根本不该出现的脚本。这篇实验记录的核心是HTML-based 和 URL-based 两种录制模式决定了你拿到的是“用户视角的界面操作脚本”还是“请求视角的 HTTP 请求脚本”并直接影响后续的开发成本。文章以 LoadRunner 自带的 WebTours 飞机订票系统为例把脚本录制、事务、参数化、集合点、关联、运行分析这几个环节串起来适合刚接触性能测试脚本录制开发的测试工程师也适合想搞清楚两种录制方式底层差异的人。2. 两种录制方式的脚本差别HTML-based 与 URL-based2.1 录制方式设置Recording Options 里的 General recording在 Virtual User GeneratorVuGen中登录 WebTours 系统前应该先确认录制方式。菜单入口是Recording - Recording Options打开后切到General recording页签。这一页里通常有两种大方向一种是描述用户操作的 HTML-based script另一种是 only explicit URLs 的 URL-based script。实验里要求两种方式各录一遍就是要对比它们生成的脚本结构。录制之前需要先启动 WebTours 服务再访问http://127.0.0.1:1080/WebTours/index.htm。第一次访问首页时服务端会生成一个userSession会话字段这个字段在后续登录提交中会用到也是后面关联问题的主角。建议录制前先清空浏览器缓存避免把无意义的静态资源请求录进脚本。2.2 HTML-based 脚本表单级动作被封装的代码长这样用 HTML-based 方式录制“登录 → 查看路线 → 退出”后生成的脚本接近下面这段Action() { web_url(index.htm, URLhttp://127.0.0.1:1080/WebTours/index.htm, Resource0, RecContentTypetext/html, Referer, Snapshott4.inf, ModeHTML, LAST); lr_think_time(10); web_submit_form(login.pl, Snapshott5.inf, ITEMDATA, Nameusername, Valuejojo, ENDITEM, Namepassword, Valuebean, ENDITEM, Namelogin.x, Value50, ENDITEM, Namelogin.y, Value11, ENDITEM, LAST); web_image(Itinerary Button, AltItinerary Button, Snapshott6.inf, LAST); web_image(SignOff Button, AltSignOff Button, Snapshott7.inf, LAST); return 0; }web_url里Resource0表示这不是资源请求而是页面导航请求RecContentTypetext/html是录制时记录到的响应类型Snapshott4.inf指向 VuGen 保存的页面快照回放时可以拿它做校验。lr_think_time(10)模拟了用户思考时间性能测试里如果关心极限并发通常会在运行时设置中把它覆盖为 0否则事务时间会偏大。web_submit_form是 HTML-based 模式的核心标志。它把用户填写并提交整个表单封装成一个动作而不是把浏览器发出的所有 HTTP 请求一条条展开。代码里只看到用户名和密码字段没有看到userSession因为这个隐藏字段被 LoadRunner 放进了Snapshott5.inf对应的表单上下文里。回放时工具会从上一个页面响应中提取隐藏字段并自动填入。这是 HTML-based 脚本短、可读性高的原因。结尾的web_image通过图片的Alt属性识别用户点击的是哪个图片按钮比如 Itinerary Button 和 SignOff Button。这种表达贴近用户操作但对性能测试来说它掩盖了真实的请求 URL一旦页面结构调整脚本很容易失效。2.3 URL-based 脚本每个请求都暴露动态值一眼可见用 URL-based 方式录制同样的操作脚本变成下面这样Action() { web_url(index.htm, URLhttp://127.0.0.1:1080/WebTours/index.htm, TargetFrame, Resource0, RecContentTypetext/html, Referer, Snapshott1.inf, ModeHTML, LAST); lr_think_time(11); web_submit_data(login.pl, Actionhttp://127.0.0.1:1080/cgi-bin/login.pl, MethodPOST, TargetFramebody, RecContentTypetext/html, Refererhttp://127.0.0.1:1080/cgi-bin/nav.pl?inhome, Snapshott2.inf, ModeHTML, ITEMDATA, NameuserSession,Value131278.147671122zHfczVQpHcAiDDDDtAfVfpHViDcf, ENDITEM, Nameusername, Valuejojo, ENDITEM, Namepassword, Valuebean, ENDITEM, NameJSFormSubmit, Valueoff, ENDITEM, Namelogin.x, Value73, ENDITEM, Namelogin.y, Value10, ENDITEM, LAST); web_url(Itinerary Button, URLhttp://127.0.0.1:1080/cgi-bin/welcome.pl?pageitinerary, TargetFramebody, Resource0, RecContentTypetext/html, Refererhttp://127.0.0.1:1080/cgi-bin/nav.pl?pagemenuinhome, Snapshott3.inf, ModeHTML, LAST); lr_think_time(4); web_url(SignOff Button, URLhttp://127.0.0.1:1080/cgi-bin/welcome.pl?signOff1, TargetFramebody, Resource0, RecContentTypetext/html, Refererhttp://127.0.0.1:1080/cgi-bin/nav.pl?pagemenuinitinerary, Snapshott4.inf, ModeHTML, LAST); return 0; }这段脚本和 HTML-based 有一个显著区别web_submit_data把登录请求的完整Actionhttp://127.0.0.1:1080/cgi-bin/login.pl和所有提交字段都列出来了包括userSession。这个userSession是服务端在用户访问首页时动态生成的一次性会话值每次会话都不一样。直接回放这段脚本userSession还是录制时的旧值服务器会拒绝登录所以必须对userSession做关联也就是从首页响应中提取新值再替换到登录请求里。URL-based 模式更适合性能测试脚本开发因为它不隐藏任何请求细节。出现登录失败或接口报错时可以直接看到是哪个 URL、哪个参数出问题。代价是脚本很长一个页面访问会被拆成 HTML 主请求和多个资源请求需要自己过滤掉静态资源。2.4 两种录制方式的选择不只看脚本长短维度HTML-based scriptURL-based script脚本粒度表单级、点击级请求级、参数级可读性高步骤少低请求多隐藏字段封装在 snapshot 中自动维护显式出现在请求里需手动关联动态数据处理部分自动完全暴露便于关联回放稳定性页面结构变化时容易挂只要 URL 和参数不变就稳定适用场景快速出脚本、页面简单复杂业务、需要分析服务器交互实际项目中我一般优先用 URL-based 录制再做关联和过滤。性能测试关心的是服务器每一条请求脚本越接近原始请求越容易定位瓶颈。HTML-based 适合功能层面的冒烟回放不适合直接拿来做大规模并发。2.5 Step Navigator从代码树理解脚本顺序录完脚本后VuGen 左侧的 Step Navigator 会按执行顺序列出每个步骤包括web_url、lr_think_time、web_submit_form等。实验要求对其中一个步骤重命名比如把web_url(index.htm)重命名为打开首页。重命名操作是在 Step Navigator 中右键选择 Rename或者在代码里直接改函数第一个字符串参数。改完后步骤名称会同步到树形视图方便后续在长脚本中快速定位某段业务。这一步看起来简单但在综合应用里很实用。当录制的脚本超过几十步时根据重命名后的业务名定位“登录”“订票”“退出”比看原始 URL 快得多。3. 脚本增强开发事务、参数化、集合点的正确插入方式3.1 用事务卡住登录操作的响应时间性能测试里不能只看单条 HTTP 请求时间因为一个操作可能包含多个请求、前端渲染和隐藏字段处理。事务Transaction就是给一段业务逻辑划定起止时间。在 VuGen 中菜单路径是Design - Insert in Script - Transactions也可以直接在代码里手写。lr_start_transaction(login); web_submit_form(login.pl, Snapshott5.inf, ITEMDATA, Nameusername, Valuejojo, ENDITEM, Namepassword, Valuebean, ENDITEM, LAST); lr_end_transaction(login, LR_AUTO);lr_start_transaction是事务起点lr_end_transaction是终点。LR_AUTO表示由 LoadRunner 根据事务内脚本的成功失败自动决定事务结果也可以用LR_PASS或LR_FAIL显式赋值。事务名最好用英文不要带空格因为 Controller 和 Analysis 中显示的事务名需要保持唯一。这里有个常见误区事务内不要包含lr_think_time。如果登录动作之前有一段 think time事务时间会被拉长测出的不是系统处理能力而是人的操作速度。实验里要查看登录响应时间应该在登录表单提交前启动事务提交完成后立即结束事务。如果要更精确地测服务器响应还可以结合扩展日志查看每个请求的实际耗时。扩展日志的设置路径是Replay - Run-Time Settings - Log - Extended logging。勾选“Parameter substitution”可以看到运行时参数替换后的实际值勾选“Server response”会把服务器返回的 HTML 内容记录到日志对排查关联和事务边界问题很有效。3.2 参数化用户名密码关键在同列取数录制脚本时用户名密码是写死的jojo/bean并发场景下所有虚拟用户共用一套账号既不合理也容易因账号被踢下线导致失败。参数化的目的是把写死的值替换成变量从外部参数文件中取值。右键选中脚本里的jojo选择Replace with a parameter创建参数名username。同样处理bean创建password。然后在 VuGen 的参数列表中编辑数据比如usernamepasswordjojobeanalice123456bobabc123脚本中对应位置会变成Nameusername, Value{username}, ENDITEM和Namepassword, Value{password}, ENDITEM。这时需要保证username和password在同一行取值否则会出现用户名和密码不配对的情况。操作方法是在参数属性中让password的Select Next Row设置为“Same line as username”而username按顺序取值。这样每次迭代取到的用户名和密码来自同一行配对关系就不会乱。参数化还有一个细节Valuelogin.x和Valuelogin.y是录制时鼠标点击登录按钮的坐标这个值在参数化后仍然保持一致不影响脚本运行。不需要参数化。3.3 集合点让多用户真正同时登录参数化解决的是数据问题集合点解决的是并发问题。VuGen 中插入集合点的菜单是Design - Insert in Script - Rendzvous生成一行lr_rendezvous(login_rendezvous);。要模拟多用户同时登录集合点应该放在登录事务开始之前而不是事务内部。lr_rendezvous(login_rendezvous); lr_start_transaction(login); web_submit_form(login.pl, Snapshott5.inf, ITEMDATA, Nameusername, Value{username}, ENDITEM, Namepassword, Value{password}, ENDITEM, LAST); lr_end_transaction(login, LR_AUTO);为什么集合点不能放事务内因为lr_rendezvous会让虚拟用户等待其他用户到达如果放在事务内等待时间会被计入事务响应时间测出来的登录耗时包含了并发调度时间数据几乎没有参考价值。正确姿势是集合点先触发等虚拟用户集合完毕再一起进入事务开始计时。在 Controller 的场景设计里可以设置集合点策略比如所有虚拟用户到达后同时释放或者按百分比释放。实验里要求“真正同时登录”通常选择 100% 用户到达后释放。3.4 订票数量与座位的参数化联动实验里有一个综合场景模拟订 1、2、3 张票并分别要求座位为 None、Window、Aisle。最简单的方式是建立一个两列参数表让数量字段和座位字段按同一行取值ticket_countseat_preference1None2Window3Aisle在订票脚本中把数量参数替换为{ticket_count}把座位参数替换为{seat_preference}。参数表的取值方式同前面一样seat_preference的Select Next Row设置为“Same line as ticket_count”保证数量 2 出来时座位一定是 Window。如果录制的脚本里座位是下拉框或单选框需要看清提交字段的名字。通常这类字段会以seatPref或num Tickets形式出现在web_submit_data的 ITEMDATA 中。替换时要保留原来的字段名只替换值不能擅自删掉 ENDITEM。更复杂的场景可以在代码里用if判断动态设置值但课程实验要求的是练习参数化用同列联动已经足够而且更容易在日志里验证。4. Controller 运行与结果分析扩展日志和输出函数定位脚本问题4.1 把脚本挂到 Controller 里跑场景脚本在 VuGen 中回放通过后关闭Replay Log的报错就可以进入 Controller 新建场景。添加脚本设置虚拟用户数比如 10 个调度策略可以设置为每 5 秒加载 2 个用户运行 5 分钟。运行结束后在 Results 中打开 Analysis查看事务摘要、响应时间曲线和错误信息。Controller 运行时虚拟用户的userSession是通过关联动态获取的所以每个虚拟用户拿到的是不同会话这就模拟出了相对真实的多用户操作。如果脚本没有做关联Controller 运行时会出现大量登录失败这个现象在结果分析中很容易暴露。4.2 用输出函数把关键参数打到日志里参数化后想确认当前迭代用的是哪一组账号可以用lr_out_message在输出窗口打日志。示例lr_out_message(用户名为%s密码为%s, lr_eval_string({username}), lr_eval_string({password}));lr_eval_string的作用是把参数表达式{username}在运行时替换成当前迭代的实际值%s是 C 语言风格的字符串占位符。这样每次迭代都会输出类似“用户名为alice密码为123456”的信息可以快速验证参数化取值是否正确。需要注意lr_out_message的输出会显示在 Replay Log 或 Controller 的 Output 窗口不影响事务结果。配合扩展日志使用时勾选“Parameter substitution”也能看到参数替换记录但输出函数更直接适合在脚本里主动埋点比如只在事务边界输出事务名和关键参数。4.3 结果分析时先看哪些数据事务响应时间要重点看平均值和 90% 响应时间而不是最大值。最大值经常受网络抖动或环境干扰没有代表性。事务摘要表中也要关注失败数哪怕失败率只有 1%也要回到 Replay Log 中定位原因。失败现象排查位置常见处理登录返回空白页或 404Replay Log 中找 login.pl 请求检查userSession是否已关联用户名密码不匹配扩展日志参数替换记录检查参数文件同行配对事务时间异常大查看 think time 是否计入运行时设置中关闭思考时间集合点后大量超时检查集合点策略和用户释放方式调整释放比例或场景加载策略结果分析不是只看 Controller 里的曲线而是要把曲线上的异常点和日志中的具体请求对应起来。这也是为什么推荐 URL-based 录制因为日志里能看到明确请求 URL定位效率高得多。4.4 回放失败时先看快照还是先看日志很多新手回放失败后习惯先看快照但快照只显示页面渲染结果看不到请求级别的错误。正确顺序应该是先打开 Replay Log定位报错的行再看该请求的服务器返回状态码最后才需要快照辅助确认页面显示。日志里如果出现HTTP 403或500基本可以断定是动态值失效或参数不匹配这时回到脚本检查关联和参数化比反复重放更有用。5. 综合应用URL 录制、Design Studio 自动关联与手动关联兜底综合实验要求录制“登录 → 定制一张票 → 退出”录制方式选择A script containing explicit URLs only也就是 URL-based 模式。录制完成后直接用原脚本回放大概率会在登录请求上失败因为前面提到的userSession是动态生成的。实验要求通过 Design Studio 自动关联解决。在 VuGen 菜单中打开Design - Design Studio选择 Correlation 页签点击扫描。它会列出脚本中被识别为动态值的位置userSession就在其中。选择后点击 Add Correlation工具会自动在脚本里插入web_reg_save_param函数并把登录请求里的旧值替换成参数引用回放就能通过。但 Design Studio 不是每次都能扫干净。如果自动关联漏掉了某个动态参数或者扫描结果里有多处需要关联而只关联了一处就需要手动兜底。手动关联的核心是在请求发出前提前从服务器响应中保存动态值。一个通用的写法放在首页请求之后、登录请求之前web_reg_save_param(userSession, LBnameuserSession\ value\, RB\, Ord1, SearchBody, LAST); web_submit_data(login.pl, Actionhttp://127.0.0.1:1080/cgi-bin/login.pl, MethodPOST, ... NameuserSession, Value{userSession}, ENDITEM, ... LAST);web_reg_save_param是一个注册型函数必须放在被测请求之前。LB和RB是左右边界表示从响应里截取nameuserSession value这个位置之后、下一个引号之前的内容。Ord1表示取第一处匹配SearchBody表示只在响应体里查找。这个边界写法对 WebTours 的登录页是有效的但遇到页面改版时需要照着重放日志里的响应内容调整左右边界。手动关联的好处是不依赖 Design Studio 的扫描策略只要知道动态值在哪个响应中出现就能手工锁定。配合扩展日志中的 Server response回放后看到日志里打印出的userSession已经变成一个新值就说明关联成功。这个兜底技巧对任何基于 URL 录制的会话类参数都适用也最能体现性能测试脚本开发的基本功。本文还有配套的精品资源点击获取
返回列表