1. LoadRunner性能测试实战精要
作为一名从业多年的性能测试工程师,我深知LoadRunner在性能测试领域的重要地位。本章将带您深入掌握LoadRunner的核心组件使用技巧、协议选择策略以及脚本开发全流程,这些都是我多年实战经验的结晶。
1.1 LoadRunner三大核心组件解析
LoadRunner由三个关键组件构成完整的性能测试工作流:
1. VuGen(Virtual User Generator)
- 脚本开发环境,支持录制和手工编写虚拟用户行为
- 提供完整的调试工具链(日志输出、断点调试等)
- 典型工作流程:录制→增强→调试→优化
- 实战建议:录制时关闭所有无关程序,确保脚本纯净度
2. Controller
- 场景设计中枢,控制虚拟用户并发策略
- 实时监控系统资源指标(CPU、内存、IO等)
- 支持分布式压力生成
- 关键功能:Rendezvous(集合点)、IP Spoofing(IP欺骗)
3. Analysis
- 测试结果分析平台
- 自动生成专业图表报告
- 支持自定义指标计算
- 数据分析技巧:重点关注90%百分位响应时间
经验之谈:三个组件建议安装在同一台性能较好的机器上,Controller和Analysis对内存需求较高,8G是基本配置。
1.2 协议选择的艺术与科学
协议选择是LoadRunner使用的第一个技术门槛,选错协议会导致录制失败或脚本不可用。根据被测系统架构,协议选择遵循以下原则:
| 系统类型 | 推荐协议 | 典型场景 |
|---|---|---|
| Web应用 | HTTP/HTML | 大多数B/S系统 |
| 文件传输 | FTP | 文件服务器 |
| 邮件系统 | IMAP/POP3/SMTP | 邮件客户端测试 |
| 数据库应用 | ODBC/JDBC | 数据库直连测试 |
| 原生客户端 | Windows Sockets | 自定义协议应用 |
| API服务 | Web Services | REST/SOAP接口 |
常见踩坑点:
- 混合协议系统要选择Multiple Protocols
- 微信小程序等新型应用可能需要选择HTTP+WebSocket
- 金融行业专用协议需要定制开发
我曾在一个政务系统项目中,因为最初只选择了HTTP协议,导致无法录制到关键的ActiveX控件交互,后来补充选择Windows Sockets协议才解决问题。
1.3 脚本开发全流程实战
1.3.1 录制技巧进阶
录制是脚本开发的第一步,但绝非简单点击记录按钮:
录制配置详解
- Application type:区分B/S(Internet Applications)和C/S(Win32 Applications)
- Program to record:指定浏览器路径(避免使用默认浏览器)
- URL Address:带协议头的完整地址(如https://)
录制过程控制
- 使用浮动工具栏灵活控制录制过程
- 合理划分Action(建议按业务模块划分)
- 避免使用浏览器回退功能(会导致脚本混乱)
录制后检查
- 检查是否生成有效脚本
- 验证关键业务步骤是否完整
- 确认没有录制到无关请求
// 典型录制生成的脚本结构 vuser_init() { // 初始化操作(如登录) return 0; } Action() { // 核心业务操作 web_url("首页", "URL=http://example.com", LAST); return 0; } vuser_end() { // 结束操作(如登出) return 0; }1.3.2 脚本优化四步法
录制生成的原始脚本往往存在冗余,需要经过优化才能用于正式测试:
清理阶段
- 删除无关请求(如广告、统计代码)
- 移除静态资源请求(可选)
- 处理EXTRARES额外资源
增强阶段
- 添加事务(Transaction)
- 插入集合点(Rendezvous)
- 设置检查点(Checkpoint)
参数化阶段
- 识别需要参数化的数据
- 设计参数化策略
- 实现动态数据替换
调试阶段
- 使用lr_output_message调试输出
- 设置断点逐步执行
- 分析回放日志
优化前后对比:我曾优化过一个电商下单脚本,从原始2000行代码精简到800行,回放成功率从60%提升到99%。
1.3.3 参数化深度解析
参数化是模拟真实用户行为的关键技术,主要解决三类问题:
- 避免重复操作(如重复下单)
- 满足数据唯一性要求(如注册测试)
- 实现数据驱动测试
参数化类型对比表:
| 类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 文件参数化 | 中小规模数据 | 配置简单 | 维护成本高 |
| 数据库参数化 | 大规模数据 | 数据实时性高 | 需要数据库支持 |
| 随机数参数化 | 无需特定值 | 使用简单 | 可控性差 |
高级参数化技巧:
- 使用Unique+Each Occurrence组合实现数据唯一性
- 参数文件采用CSV格式,支持多列数据
- 通过lr_save_string动态生成参数
// 数据库参数化示例 Action() { // 从数据库获取用户名 lr_eval_string("{db_username}"); // 使用参数化值 web_submit_data("login", "Action=http://example.com/login", "Method=POST", "Name=username", "Value={db_username}", ENDITEM, LAST); return 0; }1.3.4 关联技术实战
关联处理服务器返回的动态数据(如SessionID、Token),是脚本开发中最具挑战的部分:
关联三要素:
- 左边界(LB):动态值前的固定字符串
- 右边界(RB):动态值后的固定字符串
- 关联变量:保存提取值的变量名
关联实现步骤:
- 使用web_reg_save_param注册关联函数
- 确定左右边界(可通过对比多个回放日志)
- 验证关联值是否正确提取
// 典型关联示例 web_reg_save_param("sessionid", "LB=name=\"sessionid\" value=\"", "RB=\"", "Search=Body", LAST); web_submit_data("login", "Action=http://example.com/login", "Method=POST", LAST); // 使用关联值 web_url("homepage", "URL=http://example.com/home?sessionid={sessionid}", LAST);关联调试技巧:先用lr_output_message输出关联值验证正确性,再用于后续请求。
1.4 检查点与事务设计
1.4.1 检查点实现方案
检查点用于验证系统返回的正确性,主要有两种实现方式:
- 文本检查点
web_reg_find("Text=Login Success", "SaveCount=login_check", LAST);- 图片检查点
web_image_check("CheckLogo", "Src=/images/logo.png", LAST);检查点最佳实践:
- 只在关键业务步骤设置检查点
- 测试执行时关闭非必要检查点(影响性能)
- 结合SaveCount实现灵活验证
1.4.2 事务设计原则
事务用于衡量业务操作的性能指标,设计时应考虑:
事务粒度
- 粗粒度:如"用户登录"
- 细粒度:如"输入用户名"、"输入密码"、"点击登录"
事务嵌套
- 支持多级事务嵌套
- 避免过度嵌套影响可读性
事务状态
- LR_PASS:成功
- LR_FAIL:失败
- LR_AUTO:自动判断
// 事务典型用法 lr_start_transaction("登录流程"); web_url("登录页面", "...", LAST); lr_start_transaction("输入凭证"); web_submit_data("提交登录", "...", LAST); lr_end_transaction("输入凭证", LR_AUTO); web_url("首页", "...", LAST); lr_end_transaction("登录流程", LR_AUTO);1.5 脚本调试技巧大全
1.5.1 日志分析三板斧
回放日志
- 关注标红错误信息
- 检查关键步骤执行状态
- 验证参数化值是否正确替换
输出消息
- 使用lr_output_message输出调试信息
- 区分普通消息和错误消息(lr_error_message)
快照比对
- 录制和回放快照对比
- 使用自带浏览器查看页面差异
1.5.2 断点调试技巧
断点类型
- 行断点:暂停在指定代码行
- 条件断点:满足条件时触发
调试控制
- 单步执行(Step Over/Into)
- 继续执行(Continue)
- 停止调试(Stop)
变量监控
- 查看参数当前值
- 监控服务器返回数据
// 调试输出示例 Action() { char *username = lr_eval_string("{param_user}"); lr_output_message("当前用户:%s", username); // 设置条件断点 if(strcmp(username, "admin") == 0) { lr_output_message("管理员登录"); } return 0; }1.6 性能测试脚本设计思想
优秀的性能测试脚本应该具备以下特征:
真实性
- 模拟真实用户操作间隔(思考时间)
- 符合实际用户操作路径
- 使用生产环境数据分布
可维护性
- 清晰的脚本结构
- 充分的注释说明
- 模块化设计
健壮性
- 完善的错误处理
- 合理的超时设置
- 足够的日志信息
可扩展性
- 支持参数化扩展
- 便于添加新功能
- 适应环境变化
我在金融行业项目中总结的脚本设计checklist:
- [ ] 是否包含必要的思考时间
- [ ] 关键业务步骤是否有检查点
- [ ] 动态数据是否正确处理
- [ ] 错误处理是否完备
- [ ] 脚本是否易于维护
2. 高级脚本开发技巧
2.1 自定义函数开发
当内置函数无法满足需求时,可以开发自定义函数:
- DLL函数调用
lr_load_dll("user.dll"); user_encrypt("input", "output");- Java函数调用
lr_java_call("com.example.Utils", "encrypt", "{param1}", "ResultParam");- Web Service调用
web_service_call("StepName=EncryptData", "SOAPMethod=EncryptService|EncryptPortType|Encrypt", "ResponseParam=result", LAST);2.2 复杂逻辑处理
LoadRunner支持丰富的编程逻辑,可以处理复杂测试场景:
- 条件判断
if(strcmp(lr_eval_string("{status}"), "success") == 0) { lr_output_message("操作成功"); } else { lr_error_message("操作失败"); }- 循环控制
for(i=1; i<=10; i++) { lr_output_message("当前迭代:%d", i); // 业务操作 }- 数组处理
// 保存为参数数组 lr_save_array("value1,value2,value3", "param_array"); // 访问数组元素 lr_paramarr_idx("param_array", 1);2.3 脚本性能优化
高性能脚本可以减少资源消耗,提高测试效率:
- 减少不必要的日志
lr_set_debug_message(LR_MSG_CLASS_EXTENDED_LOG, LR_SWITCH_OFF);- 合理设置超时
web_set_timeout("CONNECT", "60", LAST);- 连接复用
web_set_sockets_option("KEEP_ALIVE", "1");- 缓存控制
web_cache_cleanup();2.4 跨协议脚本开发
复杂系统往往需要组合多个协议:
HTTP+WebSocket组合
- HTTP处理常规页面请求
- WebSocket处理实时消息
ODBC+HTTP组合
- ODBC验证数据库变更
- HTTP模拟用户操作
多协议开发要点
- 注意协议执行顺序
- 处理协议间数据传递
- 统一错误处理机制
// HTTP+ODBC组合示例 Action() { // HTTP操作 web_url("查询页面", "URL=...", LAST); // ODBC验证 lr_db_connect("StepName=连接数据库", "ConnectionString=DSN=testdb;", LAST); lr_db_executeSQLStatement("StepName=验证数据", "SQL=SELECT COUNT(*) FROM orders", "Count=", LAST); lr_db_disconnect("StepName=断开连接", LAST); return 0; }3. 实战经验总结
3.1 常见问题排查指南
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 录制无脚本生成 | 协议选择错误 | 确认被测系统使用的协议 |
| 回放时报404错误 | 动态数据未关联 | 检查URL中的动态参数 |
| 参数化不生效 | 参数文件路径错误 | 使用绝对路径指定参数文件 |
| 检查点失败 | 页面内容变化 | 更新检查点文本或边界 |
| 事务响应时间长 | 缺少思考时间 | 添加合理的思考时间 |
3.2 性能测试黄金法则
二八原则
- 20%的脚本覆盖80%的业务场景
- 优先保证核心业务流程脚本质量
逐步加压
- 从低并发开始逐步增加压力
- 观察系统性能变化曲线
结果可重复
- 确保测试环境一致性
- 记录完整的测试配置
瓶颈定位
- 先确定瓶颈类型(CPU/内存/IO/网络)
- 再分析具体原因(代码/配置/架构)
3.3 效率提升技巧
脚本模板化
- 建立常用脚本模板库
- 封装通用函数库
自动化校验
- 开发自动检查脚本
- 实现结果自动分析
团队协作
- 使用版本控制系统管理脚本
- 建立脚本评审机制
持续学习
- 关注LoadRunner新特性
- 学习性能测试新方法
在电商项目中,我们通过建立脚本模板库,使新业务脚本开发时间从3天缩短到1天,且错误率降低60%。