LoadRunner 脚本的核心结构
一个标准的 LoadRunner 脚本主要由以下几个部分组成,它们在脚本的执行流程中扮演着不同的角色。

(图片来源网络,侵删)
vuser_init()
- 作用:初始化操作,只在整个 Vuser 脚本开始时执行一次。
- 常用场景:
- 登录系统(建立会话)。
- 读取数据文件(如 CSV)。
- 初始化全局变量。
- 性能:此部分的操作不计入事务时间。
Action()
- 作用:这是脚本的核心部分,包含了主要的业务逻辑,在脚本设置为“迭代”运行时,
Action()部分的代码会被重复执行多次(迭代次数由你在 Controller 中设置)。 - 常用场景:
- 模拟用户浏览商品、加入购物车、下单等操作。
- 发起 API 请求。
- 执行数据库查询。
- 性能:此部分的所有操作都会计入事务时间。
vuser_end()
- 作用:清理操作,只在整个 Vuser 脚本结束时执行一次。
- 常用场景:
- 注销系统(销毁会话)。
- 关闭数据库连接。
- 释放内存。
- 性能:此部分的操作不计入事务时间。
LoadRunner 的核心函数库
LoadRunner 提供了丰富的函数库来帮助你与各种协议和系统交互,最常用的是 Web (HTTP/HTML) 协议的函数库。
Web (HTTP/HTML) 函数库
这是进行 Web 性能测试最核心的函数库。
-
web_reg_save_param()- 参数化/关联的利器- 作用:从服务器响应中提取数据(如 Session ID, Token, Product ID 等),并保存为一个参数,供后续请求使用,这是关联的核心函数。
- 语法:
web_reg_save_param("ParamName", "LB=\"LeftBoundary\"", // 左边界 "RB=\"RightBoundary\"", // 右边界 "Search=Body", // 在响应体中搜索 LAST); - 示例:从响应中提取
session_id。web_reg_save_param("session_id", "LB=\"session_id\":\"", "RB=\"\"", "Search=Body", LAST);之后你就可以在后续请求中使用
{session_id}来引用这个值。
(图片来源网络,侵删)
-
web_url()- 发送 GET 请求- 作用:模拟用户在浏览器中输入 URL 并回车,发起一个 GET 请求。
- 语法:
web_url("HomePage", "URL=http://example.com/index.html", LAST);
-
web_submit_data()- 发送 POST 请求- 作用:模拟表单提交,发送 POST 请求,可以包含表单数据。
- 语法:
web_submit_data("login.pl", "Action=http://example.com/login.pl", "Method=POST", "RecContentType=text/html", "Referer=http://example.com/index.html", "Mode=HTML", "Name=user", "Value={username}", // 参数化用户名 "Name=password", "Value={password}", // 参数化密码 "Name=btnSubmit", "Value=Login", LAST);
-
web_custom_request()- 最灵活的请求函数- 作用:可以构造任何类型的 HTTP 请求(GET, POST, PUT, DELETE, HEAD 等),并完全控制请求头和请求体,非常适合测试 RESTful API。
- 语法:
web_custom_request("CreateUserAPI", "URL=http://api.example.com/v1/users", "Method=POST", "EncType=application/json", // 指定内容类型为 JSON "Body={\"name\": \"{name}\", \"email\": \"{email}\"}", // 自定义请求体 "Headers={\"Authorization\": \"Bearer {token}\"}", // 自定义请求头 LAST);
参数化
参数化是让脚本更真实、更可扩展的关键,它允许你使用外部数据源(如 CSV 文件)来替换脚本中的硬编码值。
- 如何操作:
- 选中脚本中需要参数化的值(如用户名 "testuser")。
- 右键 -> Replace with a parameter。
- 创建新参数,选择数据源(如 File),并指定 CSV 文件路径。
- 在脚本中体现:
参数在脚本中用 括起来,
{username},LoadRunner 在运行时会从数据文件中按顺序读取数据替换它。
事务
事务用于衡量业务流程的性能,它会记录从 lr_start_transaction 到 lr_end_transaction 之间所有操作的响应时间。
-
语法:
lr_start_transaction("LoginTransaction"); // 开始事务 // ... 执行登录相关的请求 ... web_submit_data("login.pl", ...); lr_end_transaction("LoginTransaction", LR_AUTO); // 结束事务LR_AUTO:表示事务状态由请求的成功或失败自动决定。LR_PASS/LR_FAIL:手动设置事务状态。
关联
关联是处理“动态值”的过程,当服务器响应中包含下一次请求需要的数据时(如 Session ID),你必须通过关联提取这个数据,否则脚本会失败。
- 流程:
- 录制脚本:先录制一遍完整的业务流程。
- 查找动态值:在录制生成的日志或树视图中,找到可能变化的值(如 Session ID)。
- 使用
web_reg_save_param:在发送包含动态值的请求之前,插入web_reg_save_param函数来捕获这个值。 - 使用参数:在后续需要该值的请求中,用
{ParamName}替换原来的硬编码值。
一个完整的 Web 登录脚本示例
下面是一个模拟用户登录、浏览主页、然后退出的完整脚本。
#include "web_api.h" // Web 函数库
#include "lrw_custom.h" // 其他 LR 函数
// Action 函数,包含主要业务逻辑
Action()
{
// 定义事务:登录过程
lr_start_transaction("User_Login");
// 1. 访问登录页面
web_url("LoginPage",
"URL=http://example.com/login",
LAST);
// 2. 提交登录表单
// 假设 username 和 password 已经在参数化中设置好了
web_submit_data("SubmitLogin",
"Action=http://example.com/login_process",
"Method=POST",
"RecContentType=text/html",
"Referer=http://example.com/login",
"Mode=HTML",
"Name=username", "Value={username}", // 从参数文件读取
"Name=password", "Value={password}", // 从参数文件读取
"Name=loginBtn", "Value=Login",
LAST);
// 结束登录事务
lr_end_transaction("User_Login", LR_AUTO);
// 3. 访问用户主页(假设需要 Session ID)
// 在访问主页的请求之前,关联 Session ID
web_reg_save_param("session_id",
"LB=\"session_id\":\"",
"RB=\"\"",
"Search=Body",
LAST);
web_url("UserHomePage",
"URL=http://example.com/home",
"Referer=http://example.com/login_process",
LAST);
// 4. 退出登录
web_link("LogoutLink",
"Text=Logout",
"Snapshot=t1.inf",
LAST);
return 0;
}
// Vuser 初始化函数
vuser_init()
{
// 可以在这里打开参数文件,或者进行其他初始化操作
// lr_save_string("init_value", "global_var");
lr_output_message("Vuser is initialized.");
return 0;
}
// Vuser 结束函数
vuser_end()
{
// 在这里进行清理工作,如关闭文件等
lr_output_message("Vuser is ending.");
return 0;
}
常用 LR C 函数
除了 Web 函数,还有一些通用的 C 函数非常有用:
lr_output_message():在日志中输出信息,级别为 "Message"。lr_error_message():在日志中输出错误信息,级别为 "Error"。lr_save_string():将一个字符串保存为一个参数。lr_save_string("Hello World", "my_message"); // 之后就可以用 {my_message} 引用它lr_eval_string():获取参数的当前值。char *value = lr_eval_string("{username}"); lr_output_message("Current username is: %s", value);lr_think_time():模拟用户的思考时间,让脚本更真实。// 随机思考 1 到 5 秒 lr_think_time(lr_random_range(1, 5));
lr_save_datetime():生成当前日期时间并保存为参数。lr_save_datetime("%Y%m%d%H%M%S", DATE_NOW, "timestamp");
最佳实践
- 参数化所有硬编码值:用户名、密码、搜索关键词、产品 ID 等,都应该从数据文件中读取。
- 始终进行关联:不要假设服务器响应是静态的,使用
web_reg_save_param或 LoadRunner 的“关联”功能自动检测并处理动态值。 - 合理使用事务:将一个完整的业务流程(如“下单”)定义为一个事务,以便精确衡量其性能。
- 添加思考时间:
lr_think_time是模拟真实用户行为的关键,能让测试结果更准确,避免对服务器造成不必要的压力。 - 检查点:在关键步骤后,使用
web_reg_find函数检查页面是否包含预期的文本,以验证操作是否成功。web_reg_find("Text=Welcome", LAST); web_url("HomePage", ...);如果在响应中找不到 "Welcome",检查点会失败。
- 注释清晰:为复杂的逻辑和关键步骤添加清晰的注释,方便日后维护。
通过掌握这些核心结构、函数和最佳实践,你就可以编写出强大、可靠且高效的 LoadRunner C 语言脚本来进行各种性能测试。
