使用Loadrunner做接口或者压力测试时,我们经常会碰到请求参数中部分是来自于前置接口的情况,且是动态变化的,这时候,我们需要从前置接口响应中获取到需要的数据,然后替换到当前的接口请求参数的目标位置中,但是LR中并没有提供查找以及替换字符串的函数,前文
Loadrunner 拼接字符串(从响应中截取字段并添加新的字段作为下次请求参数)
中,我们使用字符串拼接的方式解决了这一问题,但是如果一个脚本中存在多次这种情况,现实情况也通常就是这样的,就会显得很麻烦和费力,那有没有其他的办法呢?
办法自然是有的,虽然LR中没有支持查找并替换字符串的函数,但可以自己封装一个替换字符串函数,之后需要替换时调用函数即可。
1、封装字符串替换函数lr_replace
// ----------------------------------------------------------------------------
// 参数:
// src (in) - 指向源字符串的指针
// from (in) - 指向搜索文本的指针
// to (in) - 指向替换文本的指针
//
// 返回:
// 返回一个指向包含字符串的动态分配内存的指针
// 'from' 指向的文本被替换为'to' 指向的文本。
// ----------------------------------------------------------------------------
char *strReplace(const char *src, const char *from, const char *to)
{
char *value;
char *dst;
char *match;
int size;
int fromlen;
int tolen;
size = strlen(src) + 1;
fromlen = strlen(from);
tolen = strlen(to);
value = (char *)malloc(size);
dst = value;
if ( value != NULL )
{
for ( ;; )
{
match = (char *) strstr(src, from);
if ( match != NULL )
{
size_t count = match - src;
char *temp;
size += tolen - fromlen;
temp = (char *)realloc(value, size);
if ( temp == NULL )
{
free(value);
return NULL;
}
dst = temp + (dst - value);
value = temp;
memmove(dst, src, count);
src += count;
dst += count;
memmove(dst, to, tolen);
src += fromlen;
dst += tolen;
}
else
{
strcpy(dst, src);
break;
}
}
}
return value;
}
int lr_replace( const char *lrparam, char *findstr, char *replacestr )
{
int res = 0;
int size;
char *lrp;
char *result_str;
size = strlen(lrparam) + 1;
lrp=(char *)malloc(size);
sprintf(lrp, "{%s}", lrparam);
result_str = strReplace(lr_eval_string(lrp), findstr, replacestr);
if (result_str != NULL)
{
lr_save_string(result_str, lrparam);
free(result_str);
res = 1;
}
return res;
}
2、截取用来替换的字符串purchOrderList
web_set_max_html_param_len("262144"); // 默认最大长度为256
// 从响应中截取用来替换的字符串
web_reg_save_param_ex(
"ParamName=purchOrderList", // 修改参数名,便于记忆
"LB=\"data\":{", // 修改 token 值解析算法
"RB=\"}}",
SEARCH_FILTERS,
"Scope=Body",
"RequestUrl=*/api/customize/user/getSetting?tableKey=purchOrderList-com.slip.spd.entity.vo.purch.PurchOrderVO*",
LAST);
web_custom_request("getSetting",
"URL={URL}/api/customize/user/getSetting?tableKey=purchOrderList-com.slip.spd.entity.vo.purch.PurchOrderVO",
"Method=GET",
"Resource=0",
"RecContentType=application/json",
"Referer={URL}/",
// "Snapshot=t71.inf",
"Mode=HTML",
"EncType=application/json;charset=UTF-8",
LAST);
3、保存源字母串,即用来请求的参数new_setting
// 红色head部门为需要被替换的字符串
lr_save_string("{\"curPage\": 1,\"pageSize\": 20,\"customizeUserVO\": {head\"}}},\"queryMap\":{\"deptAuth\":{\"asTbName\":\"purch_order\",\"columnName\":\"dept_id\",\"queryType\":\"IN\",\"queryCategory\":\"AND\",\"value\":\"deptAuth\"},\"supplierAuth\":{\"asTbName\":\"purch_order\",\"columnName\":\"supplier_id\",\"queryType\":\"IN\",\"queryCategory\":\"AND\",\"value\":\"supplierAuth\"},\"orderNo\":{\"queryType\":\"ALL_LIKE\",\"value\":null},\"applicationNo\":{\"queryType\":\"ALL_LIKE\",\"value\":null},\"deptId\":{\"queryType\":\"IN\",\"value\":null},\"supplierId\":{\"queryType\":\"IN\",\"value\":null},\"createUser\":{\"queryType\":\"IN\",\"value\":null},\"createTime\":{\"queryType\":\"BETWEEN\",\"value\":null},\"updateUser\":{\"queryType\":\"IN\",\"value\":null},\"updateTime\":{\"queryType\":\"BETWEEN\",\"value\":null},\"status\":{\"queryType\":\"IN\",\"value\":null},\"remark\":{\"queryType\":\"ALL_LIKE\",\"value\":null},\"purchUser\":{\"queryType\":\"IN\",\"value\":null},\"purchTime\":{\"queryType\":\"BETWEEN\",\"value\":null},\"lastReceiveTime\":{\"queryType\":\"BETWEEN\",\"value\":null},\"lastStoreTime\":{\"queryType\":\"BETWEEN\",\"value\":null},\"beforeMergeStatus\":{\"queryType\":\"IN\",\"value\":null},\"mergeType\":{\"queryType\":\"IN\",\"value\":null},\"receiveContacts\":{\"queryType\":\"IN\",\"value\":null},\"receivePhone\":{\"queryType\":\"IN\",\"value\":null},\"receiveProvince\":{\"queryType\":\"IN\",\"value\":null},\"receiveProvinceValue\":{\"queryType\":\"IN\",\"value\":null},\"receiveCity\":{\"queryType\":\"IN\",\"value\":null},\"receiveCityValue\":{\"queryType\":\"IN\",\"value\":null},\"receiveCounty\":{\"queryType\":\"IN\",\"value\":null},\"receiveCountyValue\":{\"queryType\":\"IN\",\"value\":null},\"realAddress\":{\"queryType\":\"IN\",\"value\":null}},\"groupMap\":{},\"groups\":[],\"queryParams\":{}}",
"new_setting");
4、查找并替换字符串
// 输出查看源字符串和目标字符串
lr_output_message("1_new_setting: %s",lr_eval_string("{new_setting}"));
lr_output_message("purchOrderList: %s",lr_eval_string("{purchOrderList}"));
// 用截取出的purchOrderList替换head
lr_replace("new_setting", "head", lr_eval_string("{purchOrderList}"));
// 输出替换后的字符串
lr_output_message("2_new_setting: %s",lr_eval_string("{new_setting}"));
5、查看替换结果