几乎所有报表都提供导出下载功能,在实际的业务里面用户点击“导出”按钮后随即会进行下载,在服务器硬件性能和测试机性能相差较悬殊的前提下,个人不建议在性能测试脚本中执行该步骤,原因:
1.点击导出按钮到允许下载前的时间里面,系统实际上已经执行了为报表执行下载的处理工作,仅剩的一部是保存到本地计算机,而这一步实际消耗的资源仅仅是硬件和网络的IO;
2.测试机在执行性能测试场景的过程中应该避免出现无谓的资源开销避免本地的瓶颈影响测试结果,特别是网络带宽和硬盘读写,而在多线程执行脚本下载的过程中会发生大量的写操作(fopen函数)。
简单来说,只要实现对服务器返回所有内容保存到本地,就实现了“下载”的模拟,因此思路为:
1.首先,针对所有返回内容保存到本地,这里采用关联函数可以实现web_reg_save_param
web_reg_save_param("fcontent", "LB=", "RB=", "SEARCH=BODY", LAST);
注意:由于参数SEARCH默认是针对消息头域和消息体,而我们保存目标仅在返回的body中,所以必须设置为body;
2.然后,由于关联函数保存参数的参数值默认大小为1024字节,下载文件往往不止这个size,所以在使用关联函数之前需要使用函数:web_set_max_html_param_len重新设置参数size
web_set_max_html_param_len("90000");
3.最后,把参数写入到本地文件,使用fwrite( const void *buffer, size_t size, size_t count, FILE *file_pointer );
const void *buffer:要把关联函数找到的参数作为常量写入,因此使用lr_eval_string函数把参数转换为常量
size_t size:指定缓冲区的大小,也就是服务器响应的大小,使用web_get_int_property函数取得,所以需要在导出请求后面加入:
flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE);
size_t count:指定数目,为1
FILE *file_pointer:指定写入的文件路径:
创建文件路径,使用到long fopen( const char *filename, const char *access_mode );
const char *filename参数为写入文件的路径和文件名,例如 d:\报表.xls
const char *access_mode存储模式参数为:wb,w为写,b也就是二进制模式,要求在windows中不要转义处理避免无法打开导出的报表,否则将会:
因此写:
filedes = fopen("d:\\报表.xls", "wb")
完成该步骤以后:
fwrite(lr_eval_string("{fcontent}"), flen, 1, filedes);
4.关闭文件fclose(filedes);
完成以上步骤以后,Action部分的脚本为:
web_set_max_html_param_len();web_reg_save_param(, , , , LAST);= web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE); filedes = fopen(, ); fwrite(lr_eval_string(), flen, , filedes); fclose(filedes);
但是,这个脚本仅仅能在vugen中执行,在controller中执行时本地始终为一个文件,因此再新增一个参数表作为随机号避免文件名重复,设定为每次迭代更新,例如:
并进行路径字符串连接:
int flen; long filedes; char filename[1024], *a = lr_eval_string("{流水号}");//流水号参数表防止文件重名 strcpy(filename,"D:\\信息化项目投资计划建议表"); strcat(filename,a);
场景执行时候,效果如下:
这个脚本如果在controller中直接进行性能测试的话,跟实际还是会有点差距的,由于实际业务场景里面各个用户都是选择不一样的报表进行导出,因此再对导出请求中的两个报表名进行关联,ord属性配置为参数,让vuser每次选择不一样的报表进行导出,例如:
web_reg_save_param_ex( "ParamName=CorrelationParameter_2", "LB=\">", "RB=</a></td>", "Ordinal={报表行数}", SEARCH_FILTERS, "Scope=Body", "RequestUrl=*/CsgPlanDrawReportQuery.jsp*", LAST);
最后,就实现了报表模块中,针对各个不同报表执行导出操作并下载到本地的性能测试目的。