一.关联函数:该函数的功能很强大
1.用#代表任何数字
2.使用^代表通配符
3.获取匹配到的第几个值
4.找不到时报error还是报警,建议报警,这样程序还能继续执行
5.搜索范围,建议选择全部
6.类似 java中的substring方法,从第10个字符开始截取到第50个字符
7.忽略重定向
二.关联数组
1.要实现的一个需求是进入csdn首页,能够随机点击左侧导航栏进入到相应的栏目中
2.比如进入程序人生
3.链接是https://www.youkuaiyun.com/nav/career,每个栏目的域名相同,后面部分不同
3.1.要从首页的源码中查看每个栏目后面的部分信息,然后提取到一个数组中
4.脚本已经录制完成,在脚本中添加步骤添加函数
5.要给引号加转义符
6.打印:lr_output_message(lr_eval_string("{getitems}"));因为是数组所以打印结果是
7.打印出第二个:lr_output_message(lr_eval_string("{getitems_2}"));
8.获取全部的值
//获取数组的长度的函数lr_paramarr_len("getitems")
//lr_paramarr_idx("getitems",i)根据下标索引获取数组中的数据
for(i=1;i<=lr_paramarr_len("getitems");i++){
lr_output_message(lr_paramarr_idx("getitems",i));
}
8.1.随机获取一个值
r_output_message(lr_paramarr_random("getitems"));
8.2.使用sprintf给一个变量赋值
//sprintf(myurlstring,"{getitems_%d}",i); 是把"{getitems_%d}"的值赋值给myurlstring,myurlstring是char数组,必须用数组才行要不然会报错,并打印出来
for(i=1;i<=lr_paramarr_len("getitems");i++){
sprintf(myurlstring,"{getitems_%d}",i);
lr_output_message(lr_eval_string(myurlstring));
}
//保存参数的函数lr_save_string(第一个参数是参数值,第二个参数是参数名称可以随意设置),这个参数testurl可以被下面的函数使用
lr_save_string(lr_paramarr_random("getitems"),"testurl");
lr_output_message(lr_eval_string("{testurl}"));
8.3.拼接参数并关联应用到下面的函数中
//拼接要访问的url
sprintf(askurlstring, "https://www.youkuaiyun.com%s", lr_paramarr_random("getitems"));
lr_output_message(askurlstring);//打印变量查看变量有没有拼接成功
//把拼接的url保存到一个变量中这样才能被下面的函数应用
lr_save_string(askurlstring,"askurlstring");
//访问拼接的url
web_url("career",
"URL={askurlstring}",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t113.inf",
"Mode=HTML",
LAST);
9.实例:打开csdn的首页,然后随机选中一个栏目,再进入栏目中随机点击一篇文章
Action_Allcode()
{
//变量的声明必须放到前面,开始执行代码后不能声明变量
//声明一个变量,必须放到首行这个位置才行
int i;
//声明一个char变量,用来存放拼接的URL地址
char* urlstring="https://www.youkuaiyun.com";
//声明一个长度为1024的char数组,下面没有用到
char myurlstring[1024];
//声明一个长度为1024的char数组,应用到下面的url中
char askurlstring[1024];
//声明一个char变量,用于存放栏目的名称
char *askurltitle;
web_set_sockets_option("SSL_VERSION", "TLS1.1");
web_add_cookie("Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_19814196820-1526528487575-539618; DOMAIN=www.youkuaiyun.com");
web_add_cookie("uuid_tt_dd=10_19814196820-1526528487575-539618; DOMAIN=www.youkuaiyun.com");
web_add_cookie("dc_tos=ptyfw6; DOMAIN=www.youkuaiyun.com");
web_add_cookie("dc_session_id=10_1526528487575.516753; DOMAIN=www.youkuaiyun.com");
web_add_cookie("Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1561970163; DOMAIN=www.youkuaiyun.com");
web_add_cookie("TY_SESSION_ID=47e865f3-1857-4c8d-8791-ab14094f7f4f; DOMAIN=www.youkuaiyun.com");
web_reg_save_param("getitems",
"LB/ALNUMLC=<li class=\"\"><a href=\"",
"RB=\">",
"Ord=ALL",
LAST);
// web_reg_save_param_regexp(
// "ParamName=getitems",
// "RegExp= <li class=\"\"><a href=\"/nav/.*\">.*</a></li>",
// "Group=0",
// SEARCH_FILTERS,
// LAST);
web_url("www.youkuaiyun.com",
"URL=https://www.youkuaiyun.com/",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t109.inf",
"Mode=HTML",
EXTRARES,
"Url=/images/icon_close_big.png", ENDITEM,
"Url=/images/is_top_big.png", ENDITEM,
"Url=/favicon.ico", "Referer=", ENDITEM,
"Url=/images/icon_close_hover_big.png", ENDITEM,
LAST);
// //打印出数组的第二个值,数组的下标是从1开始的,所以第二个是2
// lr_output_message(lr_eval_string("{getitems_2}"));
//
//
// //获取数组的长度的函数lr_paramarr_len("getitems")
// //lr_paramarr_idx("getitems",i)根据下标索引获取数组中的数据
// for(i=1;i<=lr_paramarr_len("getitems");i++){
// lr_output_message(lr_paramarr_idx("getitems",i));
// }
//lr_paramarr_random("getitems")随机获取数组中的数据
// lr_output_message(lr_paramarr_random("getitems"));
//sprintf(myurlstring,"{getitems_%d}",i); 是把"{getitems_%d}"的值赋值给myurlstring,myurlstring是char数组,必须用数组才行要不然会报错,并打印出来
// for(i=1;i<=lr_paramarr_len("getitems");i++){
// sprintf(myurlstring,"{getitems_%d}",i);
// lr_output_message(lr_eval_string(myurlstring));
// }
//保存参数的函数lr_save_string(第一个参数是参数值,第二个参数是参数名称可以随意设置),这个参数testurl可以被下面的函数使用
// lr_save_string(lr_paramarr_random("getitems"),"testurl");
// lr_output_message(lr_eval_string("{testurl}"));
//拼接要访问的url
sprintf(askurlstring, "https://www.youkuaiyun.com%s", lr_paramarr_random("getitems"));
lr_output_message(askurlstring);//打印变量查看变量有没有拼接成功
//把拼接的url保存到一个变量中这样才能被下面的函数应用
lr_save_string(askurlstring,"askurlstring");
//多次迭代web_url的名称都一样,本来想实现名称要根据点击的url变化,web_url的名称不能用变量参数
//从字符串后面开始搜索'/',找到后直接截取包含'/'的后面的内容
askurltitle=(char *)strrchr(askurlstring,'/');
lr_save_string(askurltitle,"askurltitlestring");//保存到askurltitlestring中并打印查看结果
lr_output_message(lr_eval_string("{askurltitlestring}"));
//添加一个关联参数,从随机进入的栏目返回的结果中获取文章url
web_reg_save_param("articleurl",
"LB=data-track-view='{\"mod\":\"popu_459\",\"con\":\",",
"RB=,",
"Ord=ALL",
LAST);
//访问拼接的url
web_url("career",
"URL={askurlstring}",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t113.inf",
"Mode=HTML",
LAST);
// //打印输出获取到的articleurl值
// lr_output_message(lr_eval_string("{articleurl}"));
//
// //打印输出关联数组中的每一个值,并存到变量中
// for(i=1;i<=lr_paramarr_len("articleurl");i++){
// lr_output_message(lr_paramarr_idx("articleurl",i));
// }
//从访问的栏目url中随机取一个articleurl值并存到变量中
lr_save_string(lr_paramarr_random("articleurl"),"articleurlstring");
lr_output_message(lr_eval_string("{articleurlstring}"));
web_url("89089809",
"URL={articleurlstring}",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
"Referer=https://www.youkuaiyun.com/nav/career",
"Snapshot=t118.inf",
"Mode=HTML",
EXTRARES,
"Url=https://www.youkuaiyun.com/favicon.ico", "Referer=", ENDITEM, "Url=https://pagead2.googlesyndication.com/pagead/js/r20190626/r20190131/show_ads_impl.js", ENDITEM,
"Url=https://pagead2.googlesyndication.com/pub-config/r20160913/ca-pub-1076724771190722.js", ENDITEM,
"Url=https://www.googletagservices.com/activeview/js/current/osd.js?cb=%2Fr20100101", ENDITEM,
"Url=https://entry.baidu.com/rp/bwordcom?di=&user=&page_url=https%3A%2F%2Fblog.youkuaiyun.com%2FPx01Ih8%2Farticle%2Fdetails%2F89089809&logid=111&title=%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AE%97%E6%B3%95%20-%20ConcurrentHashMap%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%20-%20%3Csdffdsfsdfdfs%3Esfsfsfsdfsdffds%3C%2FsdfsDS%3EFsd%20-%20优快云%E5%8D%9A%E5%AE%A2&jsonp=baidu_bw_1562048038258", ENDITEM,
LAST);
return 0;
}
三.事务
1.统计每一个请求或者每一批请求的响应时间,评估系统的处理速度
1.1.统计事务的成功率:评估系统的稳定性
1.2.自动事务有两个选项:按每一个操作action为一个事务、按每一个步骤为一个事务
2.保存action,创建controller场景,运行查看按每一个action为一个事务的执行情况
3.运行完毕,点击事务响应时间查看结果,显示最大值、最小值、平均值等信息
4.再设置按每一个步骤为一个事务查看响应时间
5.可以不勾选自动事务,也可以勾选,不冲突,手动设置事务
6.手动定义三个事务,进入controller场景中运行查看事务响应时间
四.检查点
1.loadrunner结束事务中的LR_AUTO只是通过状态码来区分事务是否成功
1.1.比如登录时密码错误,能正常返回界面告诉用户密码错误请重新输入密码
1.2.对loadrunner来说检测到服务器返回是200的状态码,所以检测到事务成功
1.3.但是从业务角度来说并没有成功,所以需要通过检查点来判断事务是否真正的成功
1.4.插入函数,函数要放到请求之前,可以按文本去查也可以按字符串去查
2.根据统计次数大于等于1判断请求成功
五.思考时间
1.思考时间就是模拟用户暂停发请求的时间,为让loadrunner模拟真实的场景,是需要使用思考时间的
2.思考时间定为5秒,按最小值50%,最大值200%随机选取思考时间
七.集合点
1.集合点适用场景是并发测试,主要关注大用户量的并发
1.1.所有用户都在并发请求,请求的模块可能是不同的
1.2.所有用户都在提交同一个请求
2.集合点是不能模拟真实场景,至少不能很绝对的模拟
2.1.因为不可能达到绝对的并发,服务器接收到请求也是有先后顺序的
2.2.处理请求也是需要队列处理,所以达不到绝对意义的并发
2.3.并发测试:相对严格的并发,并没有绝对严格的并发测试。并发测试属于压力测试的一个子集
2.4.压力测试:关注系统最大的瓶颈是多少,系统在什么时候会发生崩溃,系统在什么样的场景下会发生崩溃
2.4.1.并发测试属于压力测试的一个子集。做压力测试时不需要设置思考时间,直接压测就行。
2.5.负载测试:当系统有100个人、1000个人、10000个人访问的时候系统的处理情况是什么,cpu、内存、数据库等的表现是什么样的
2.6.稳定性测试:系统在标准用户数、最佳状态下的长时间的一种运行
2.6.1.比如cpu利用率在70%~80%左右,资源充分利用并且还有上升的空间的一种状态
2.7.系统的最大用户数:是指某一个指标出现极限时的一种状态,不可能所有指标都出现极限状态
2.7.1.比如内存到达极限,或者cpu到达极限等等
2.8.容量测试:模拟系统长时间运行后的性能状态,目前流行的关系型数据库中都有自己的存储引擎
2.8.1.比如使用索引、关键字等可以很快速的查询出数据
2.8.2.比如查询1000条和查询1亿条时数据库的处理速度是什么样的,sql语句是否要优化等的测试
3.先创建事务,再创建集合点就会出现事务统计的时间不准确的情况
3.1.因为因为集合点是要等所有用户到达后统一去发起下一个请求
3.2.所以集合点中有一个等待的时间,暂停的时间是要统计到事务的时间中的
3.3.所以集合点不能放到事务里面要放到外面,这样事务统计的时间才准确
4.模拟场景一:集合点放在事务里面,查看统计时间
4.1.每隔10秒会释放5个用户
4.2.事务的响应时间
5.模拟场景二:集合点放在事务外面,查看统计时间
5.1.前5秒先运行5个用户,其他用户等待状态
5.2.到时间再释放5个
5.3.全部释放开始运行
5.4.事务响应时间:可见最大时间比上一个场景的时间小,最后一个运行时间也变小
6.模拟场景三:上两个场景持续运行时间太长,导致一些虚拟用户迭代失败,现在改成持续运行3分钟
6.1.可以看出后到集合点的用户已用时间短
6.2.了解场景中的集合
6.3.每隔10秒释放5个用户,在场景中设置当运行的用户到达时就可以开始发出请求
6.4.第一个选项是说当所有的虚拟用户都到达时才发出请求
6.4.1.与设置的每隔10秒释放5个用户是有冲突的,这样每隔10秒释放5个用户
6.4.2.释放后用户要等待,等待所有的用户都被释放后才发出请求
6.5.vuser之间的超时值设置为10秒,是说当选中第一个选项时
6.5.1.在用户还没到达但是已经超时就不再等待用户,直接发出请求,这样不浪费时间
6.6.这个配置是说当有1个用户到达时就发出请求
6.7.一般使用默认的配置就可以
6.8.模拟场景四,设置等所有用户到达时才发起请求
八.调试
九.函数总结
1.lr_output_message(lr_eval_string("{参数名称}"))打印结果是否获取成功
2.web_reg_save_param_ex()关联参数
3.web_reg_save_param()关联函数
4.lr_paramarr_len("getitems")获取数组的长度
5.lr_paramarr_idx("getitems",i)根据下标索引获取数组中的数据
6.lr_paramarr_random("getitems")随机获取数组中的数据
7.sprintf(myurlstring,"{getitems_%d}",i); 是把"{getitems_%d}"的值赋值给myurlstring,myurlstring是char数组,必须用数组才行要不然会报错
8.lr_save_string(lr_paramarr_random("getitems"),"testurl");//lr_save_string(第一个参数是参数值,第二个参数是参数名称可以随意设置)
9.web_reg_find检查点函数,要放到请求之前
10.lr_log_message("要打印的日志内容");
11.lr_get_attrib_string("在运行时设置中其他属性的参数名称")
12.web_custom_request()发送自定义请求,与web_url,web_sumbit_data()一样
13.web_add_header("content_type","application/json")增加请求头
14.web_get_int_property(HTTP_INFO_RETURN_CODE)获取上一个请求的返回码
十.补充
1.lr_get_attrib_string("在运行时设置中其他属性的参数名称")
lr_continue_on_error(1);//出现错误继续执行
//中间可以放要执行的代码
lr_continue_on_error(0);//出现错误不继续执行,关闭开关,与运行时设置的遇到错误继续执行是一样的
2.web_get_int_property(HTTP_INFO_RETURN_CODE)获取上一个请求的返回码