ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LoadRunner性能测试核心技术与实战指南

LoadRunner性能测试核心技术与实战指南

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 ServicesREST/SOAP接口

常见踩坑点:

  1. 混合协议系统要选择Multiple Protocols
  2. 微信小程序等新型应用可能需要选择HTTP+WebSocket
  3. 金融行业专用协议需要定制开发

我曾在一个政务系统项目中,因为最初只选择了HTTP协议,导致无法录制到关键的ActiveX控件交互,后来补充选择Windows Sockets协议才解决问题。

1.3 脚本开发全流程实战

1.3.1 录制技巧进阶

录制是脚本开发的第一步,但绝非简单点击记录按钮:

  1. 录制配置详解

    • Application type:区分B/S(Internet Applications)和C/S(Win32 Applications)
    • Program to record:指定浏览器路径(避免使用默认浏览器)
    • URL Address:带协议头的完整地址(如https://)
  2. 录制过程控制

    • 使用浮动工具栏灵活控制录制过程
    • 合理划分Action(建议按业务模块划分)
    • 避免使用浏览器回退功能(会导致脚本混乱)
  3. 录制后检查

    • 检查是否生成有效脚本
    • 验证关键业务步骤是否完整
    • 确认没有录制到无关请求
// 典型录制生成的脚本结构 vuser_init() { // 初始化操作(如登录) return 0; } Action() { // 核心业务操作 web_url("首页", "URL=http://example.com", LAST); return 0; } vuser_end() { // 结束操作(如登出) return 0; }
1.3.2 脚本优化四步法

录制生成的原始脚本往往存在冗余,需要经过优化才能用于正式测试:

  1. 清理阶段

    • 删除无关请求(如广告、统计代码)
    • 移除静态资源请求(可选)
    • 处理EXTRARES额外资源
  2. 增强阶段

    • 添加事务(Transaction)
    • 插入集合点(Rendezvous)
    • 设置检查点(Checkpoint)
  3. 参数化阶段

    • 识别需要参数化的数据
    • 设计参数化策略
    • 实现动态数据替换
  4. 调试阶段

    • 使用lr_output_message调试输出
    • 设置断点逐步执行
    • 分析回放日志

优化前后对比:我曾优化过一个电商下单脚本,从原始2000行代码精简到800行,回放成功率从60%提升到99%。

1.3.3 参数化深度解析

参数化是模拟真实用户行为的关键技术,主要解决三类问题:

  1. 避免重复操作(如重复下单)
  2. 满足数据唯一性要求(如注册测试)
  3. 实现数据驱动测试

参数化类型对比表:

类型适用场景优点缺点
文件参数化中小规模数据配置简单维护成本高
数据库参数化大规模数据数据实时性高需要数据库支持
随机数参数化无需特定值使用简单可控性差

高级参数化技巧:

  1. 使用Unique+Each Occurrence组合实现数据唯一性
  2. 参数文件采用CSV格式,支持多列数据
  3. 通过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),是脚本开发中最具挑战的部分:

关联三要素:

  1. 左边界(LB):动态值前的固定字符串
  2. 右边界(RB):动态值后的固定字符串
  3. 关联变量:保存提取值的变量名

关联实现步骤:

  1. 使用web_reg_save_param注册关联函数
  2. 确定左右边界(可通过对比多个回放日志)
  3. 验证关联值是否正确提取
// 典型关联示例 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 检查点实现方案

检查点用于验证系统返回的正确性,主要有两种实现方式:

  1. 文本检查点
web_reg_find("Text=Login Success", "SaveCount=login_check", LAST);
  1. 图片检查点
web_image_check("CheckLogo", "Src=/images/logo.png", LAST);

检查点最佳实践:

  • 只在关键业务步骤设置检查点
  • 测试执行时关闭非必要检查点(影响性能)
  • 结合SaveCount实现灵活验证
1.4.2 事务设计原则

事务用于衡量业务操作的性能指标,设计时应考虑:

  1. 事务粒度

    • 粗粒度:如"用户登录"
    • 细粒度:如"输入用户名"、"输入密码"、"点击登录"
  2. 事务嵌套

    • 支持多级事务嵌套
    • 避免过度嵌套影响可读性
  3. 事务状态

    • 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 日志分析三板斧
  1. 回放日志

    • 关注标红错误信息
    • 检查关键步骤执行状态
    • 验证参数化值是否正确替换
  2. 输出消息

    • 使用lr_output_message输出调试信息
    • 区分普通消息和错误消息(lr_error_message)
  3. 快照比对

    • 录制和回放快照对比
    • 使用自带浏览器查看页面差异
1.5.2 断点调试技巧
  1. 断点类型

    • 行断点:暂停在指定代码行
    • 条件断点:满足条件时触发
  2. 调试控制

    • 单步执行(Step Over/Into)
    • 继续执行(Continue)
    • 停止调试(Stop)
  3. 变量监控

    • 查看参数当前值
    • 监控服务器返回数据
// 调试输出示例 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 性能测试脚本设计思想

优秀的性能测试脚本应该具备以下特征:

  1. 真实性

    • 模拟真实用户操作间隔(思考时间)
    • 符合实际用户操作路径
    • 使用生产环境数据分布
  2. 可维护性

    • 清晰的脚本结构
    • 充分的注释说明
    • 模块化设计
  3. 健壮性

    • 完善的错误处理
    • 合理的超时设置
    • 足够的日志信息
  4. 可扩展性

    • 支持参数化扩展
    • 便于添加新功能
    • 适应环境变化

我在金融行业项目中总结的脚本设计checklist:

  • [ ] 是否包含必要的思考时间
  • [ ] 关键业务步骤是否有检查点
  • [ ] 动态数据是否正确处理
  • [ ] 错误处理是否完备
  • [ ] 脚本是否易于维护

2. 高级脚本开发技巧

2.1 自定义函数开发

当内置函数无法满足需求时,可以开发自定义函数:

  1. DLL函数调用
lr_load_dll("user.dll"); user_encrypt("input", "output");
  1. Java函数调用
lr_java_call("com.example.Utils", "encrypt", "{param1}", "ResultParam");
  1. Web Service调用
web_service_call("StepName=EncryptData", "SOAPMethod=EncryptService|EncryptPortType|Encrypt", "ResponseParam=result", LAST);

2.2 复杂逻辑处理

LoadRunner支持丰富的编程逻辑,可以处理复杂测试场景:

  1. 条件判断
if(strcmp(lr_eval_string("{status}"), "success") == 0) { lr_output_message("操作成功"); } else { lr_error_message("操作失败"); }
  1. 循环控制
for(i=1; i<=10; i++) { lr_output_message("当前迭代:%d", i); // 业务操作 }
  1. 数组处理
// 保存为参数数组 lr_save_array("value1,value2,value3", "param_array"); // 访问数组元素 lr_paramarr_idx("param_array", 1);

2.3 脚本性能优化

高性能脚本可以减少资源消耗,提高测试效率:

  1. 减少不必要的日志
lr_set_debug_message(LR_MSG_CLASS_EXTENDED_LOG, LR_SWITCH_OFF);
  1. 合理设置超时
web_set_timeout("CONNECT", "60", LAST);
  1. 连接复用
web_set_sockets_option("KEEP_ALIVE", "1");
  1. 缓存控制
web_cache_cleanup();

2.4 跨协议脚本开发

复杂系统往往需要组合多个协议:

  1. HTTP+WebSocket组合

    • HTTP处理常规页面请求
    • WebSocket处理实时消息
  2. ODBC+HTTP组合

    • ODBC验证数据库变更
    • HTTP模拟用户操作
  3. 多协议开发要点

    • 注意协议执行顺序
    • 处理协议间数据传递
    • 统一错误处理机制
// 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 性能测试黄金法则

  1. 二八原则

    • 20%的脚本覆盖80%的业务场景
    • 优先保证核心业务流程脚本质量
  2. 逐步加压

    • 从低并发开始逐步增加压力
    • 观察系统性能变化曲线
  3. 结果可重复

    • 确保测试环境一致性
    • 记录完整的测试配置
  4. 瓶颈定位

    • 先确定瓶颈类型(CPU/内存/IO/网络)
    • 再分析具体原因(代码/配置/架构)

3.3 效率提升技巧

  1. 脚本模板化

    • 建立常用脚本模板库
    • 封装通用函数库
  2. 自动化校验

    • 开发自动检查脚本
    • 实现结果自动分析
  3. 团队协作

    • 使用版本控制系统管理脚本
    • 建立脚本评审机制
  4. 持续学习

    • 关注LoadRunner新特性
    • 学习性能测试新方法

在电商项目中,我们通过建立脚本模板库,使新业务脚本开发时间从3天缩短到1天,且错误率降低60%。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进