LoadRunner关联技术是性能测试脚本开发中最重要、最具挑战性的步骤,本质是在服务器响应中捕获动态变化的值,并将其保存为参数,以供后续请求使用。
实现准确关联的完整技术途径:
关联的原理和前置工作
在实施关联前,必须完成一次重点的脚本比对分析:
录制两份脚本:使用相同操作流程(如登录-退出),在不同时间或会话下录制两次。
进行差别对比:使用文本对比工具(如Beyond Compare)或VuGen的比对功能,分析两份脚本。那些在两次录制中值不同,但长度和格式相似的字符串,就是需要关联的头号嫌疑对象(如sessionID=asDf123GhJ 和 sessionID=zXcV456BnM)。
实战关联技术详解
1. 自动关联:
自动关联适用于边界清晰、方式固定的简单动态值。
录制时自动关联:在VuGen的录制选项中启用,LoadRunner会在录制过程中根据内置规则自动关联常见动态值(如ASP.NET的__VIEWSTATE)。
录制后扫描关联:脚本录制完成后,通过菜单 Tools -> Scan Script for Correlations 或使用快捷键 Ctrl+F8 启动扫描。Vugen会对比录制快照,建议关联项,由您确定创建。
回放时扫描关联:在Run-time Settings -> Internet Protocol -> Correlation 中启用。脚本回放时,如果遇到“^”包围的未关联动态值(如“^a23f4e^”),VuGen会提示是不是创建关联。
局限性:自动关联难以应对复杂边界、多次出现的相似内容或自定义格式的动态数据。
2. 手动关联:
手动关联是处理复杂情形的必备技能,重要是使用关联函数。最常用的是 web_reg_save_param_ex。
函数分析和示例:
c
int web_reg_save_param_ex(
const char *ParamName, // 参数名,后续用 {ParamName} 引用
const char *LB, // 左边界 (Left Boundary)
const char *RB, // 右边界 (Right Boundary)
const char *SearchIn, // 搜索范围:一般为 "Body", "Headers", "Noresource"
int Ordinal, // 第几次一致 (Ordinal),默认1
int Instance, // 实例号 (Instance),和Ordinal共同定位
const char *RelFrameId, // 关联框架ID
int NotFound, // 未找到时的处理:ERROR(默认) 或 WARNING
LAST);
准确定位方法(Ordinal和Instance):
Ordinal=1, Instance=1:一致第一个满足左/右边界的值(默认)。
Ordinal=1, Instance=ALL:捕获所有满足左/右边界的值,并存入数组。后续可通过 {ParamName_1}, {ParamName_2}... 访问。
当页面中有多个结构相同、值不同的区域(如商品列表),需要捕获特定位置的值时,需组合使用Ordinal和Instance进行精确定位。
高级边界和转义:
使用正则表达式:在左右边界字符串前添加 "RegExp=" 前缀,以启用正则一致。如,一致任意长度的数字串:LB/IC=RegExp=orderID=\"\d+\"。
转义特殊字符:如果边界中包含引号(")、斜杠(\)等特殊字符,必须使用反斜杠(\)进行转义。这是手动关联中最常见的错误来源之一。如,对于边界 "value=\",在代码中应写作 LB=value=\\"。
3. 处理复杂响应格式(JSON/XML)
对于结构化的API响应,手动关联结合正则表达式或专门的分析函数更高效。
JSON响应示例:假设响应为 {"token": "abc123", "userid": 456},要捕获token。
c
// 方法1:使用正则表达式边界
web_reg_save_param_ex(
"ParamName=token",
"LB/IC=RegExp=\"token\":\\s*\"([^\"]+)",
"RB/IC=\"",
...);
// 方法2(更优):使用web_reg_save_param_json函数(如支持)
XML响应处理:可使用 web_reg_save_param_xpath 函数通过XPath途径准确定位节点。
关联故障排查和检查
当关联失败时,请按照以下步骤系统化排查:
启用并分析详细日志:在 Run-time Settings -> Log 中,启用 Extended log 并勾选 Data returned by server。回放脚本,在日志中搜索你试图关联的参数名,查看服务器实际返回的完整响应,确定边界字符串是不是正确。
检查关联函数放置位置:关联函数必须位于引发该响应的请求之前,且在任何可能使用该参数值的请求之前。它是注册型函数,只在下一个请求完成后执行捕获。
证实边界唯一性和稳定性:在日志中检查你设定的左边界(LB)和右边界(RB)是不是能在响应中唯一、稳定地标识出目的动态值。如果同一边界一致了多处内容,需使用 Ordinal 和 Instance 进行调整。
检查特殊字符和空格:肉眼不可见的换行符、制表符或空格可能在响应中存在。在日志中仔细核对,必要时在边界中使用 \n, \t, \s* 等通配符。
专业实践检查清单
脚本比对:已完成至少两份相同操作脚本的录制和差别对比,确定关联目的。
函数放置:所有 web_reg_save_param_ex 等关联函数均已准确放置在被捕获请求之前。
边界确定:通过详细日志证实,左右边界能在响应中唯一一致到目的文本。
特殊字符处理:边界字符串中的引号、斜杠等已正确转义。
参数使用:关联得到的参数 {ParamName} 已正确替换到后续所有相关请求中。
错误处理:已根据业务思路合理设置 NotFound 属性(如,对于登录令牌,未找到时应 ERROR;对于可选字段,可设为 WARNING)。
迭代和并发:在Controller情形中,使用多个Vuser和多次迭代运行脚本,证实关联参数在并发和不断运行下仍能正确获取且无冲突。