Jmeter文件上传和下载实践

1 简单的上传和下载

1.1 文件上传接口测试

选择Files Upload,填写相应参数:

  1. File Path:填写绝对路径
  2. Parameter Name:根据实际请求中的参数填写
  3. MIME Type:根据实际请求中的参数填写
  4. Use multipart/from-data for HTTP POST 勾选上(发现在5.5版本中,不勾选也没影响,发送的请求默认就时multipart/from-data,其他版本未进行验证)
    在这里插入图片描述

几点说明:
(1) MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。(来源:百度百科)
(2) 实际使用中发现一个,MIME Type这个参数不论填写什么,都不影响文件的正确上传,但是必须要有值。结合上面MIME的简介,猜想这个值对文件的解析是没有作用的,很多系统文件上传都是指定模板的,并不需要这个参数(仅为猜想)在这里插入图片描述
(3) 很多文章里面说Client implementation选择java,实际使用中没有勾选,也不影响文件的上传。在这里插入图片描述
实际上很多使用java的是为了避免特殊字符被编码,而这跟post请求的编码方式有关,FORM表单的 enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。默认地,表单数据会编码为 “application/x-www-form-urlencoded”。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)。

描述
application/x-www-form-urlencoded在发送前编码所有字符(默认)
multipart/form-data不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
application/json在发送前编码所有字符(默认)
text/plain空格转换为 “+” 加号,但不对特殊字符编码。

(4) 查了一下java和HttpClient4的介绍。主要区别为
Java:选择压测时,链接是复用的(代码中的http调用都加了连接池)
httpclient4:压测时,每请求一次都创建一个新的链接,(jmeter5.0以前默认关闭了连接复用,5.0上是打开的:即每请求一次都会创建一个新的链接)
从JMeter 5.0开始,当使用默认的HC4实现时,JMeter将在每个线程组迭代时重置HTTP状态(SSL状态+连接)。如果您不想要此行为,请设置httpclient.reset_state_on_thread_group_iteration = false
所以httpclient4 在连接复用设置打开的情况下,压测结果与java的是不一样的,因为java复用链接,httpclient4每次连接都会重新建立tcp连接,如果httpclient4吞吐量过低,需要考虑网络带宽的限制
java实现适合压榨性测试,httpclient4适合真实场景的模拟。
(5) 可能在application/x-www-form-urlencoded下,使用java特殊字符没有编码是一个巧合,并不是特意为之?

1.2 文件下载接口测试

  1. 文件下载,如果仅测试接口是否返回了数据,而不把文件保存到本地,和常规的接口测试是一样的,只不过返回的数据是字节流,我们看起来像是乱码(如何在结果树中直接查看文件内容,可参看文章《JMeter在结果树中直接查看文件内容》)
    在这里插入图片描述
    在这里插入图片描述

  2. 可以添加【Size Assertion】进行断言。因为每一次的大小会有变化,可以将返回的大小数据适当降低,然后使用大于或大于等于进行判断。
    在这里插入图片描述
    在这里插入图片描述

2 文件下载到本地

2.1 固定文件路径

  • 把文件下载到本地,需要添加BeanShell PostProcessor,然后写入代码。
  • 如果不指定具体的存储路径,会默认将默认存在JMEGER_HOME/bin目录下。
  • 或者直接指定类似“D://Download/下载的文件.xlsx”的绝对路径。
import java.io.*;

byte[] result = prev.getResponseData(); //获取请求的返回
String fileName = "下载的文件.xlsx"; //代表存放文件的位置和文件名,只有文件名,默认存在JMEGER_HOME/bin目录下
File file = new File(fileName);
FileOutputStream out = new FileOutputStream(file);
out.write(result);

out.close();

在这里插入图片描述

2.2 相对文件路径

String fileName = "../下载的文件.xlsx";//在JMEGER_HOME/bin目录的上一级目录下,即存在JMEGER_HOME目录下

2.3 根据脚本路径存放

  • 获得执行脚本所在的路径,再获取其父路径,然后和指定目录及文件名拼接,实现存在脚本路径的父路径下的result目录中,保存文件之前先进行删除,避免文件存在,jmeter报错。
  • 分隔符问题:windows分割符为\,linux为/,当前windows也可以识别/,因此可以统一使用/,如果在windows下使用\,需要转义一下,即使用\,另外还可以通过System.getProperty(“file.separator”)来获取系统分隔符。
fileName = strParentDirectory +"/result/" + fileName; 
ileName = strParentDirectory +"\\result\\" + fileName;  //winows下也可以
fileName = strParentDirectory +System.getProperty("file.separator") +"result"+System.getProperty("file.separator") + fileName;  //使用系统分割符

完整的代码:

import java.io.*;
import org.apache.jmeter.services.FileServer;

String baseDir=FileServer.getFileServer().getBaseDir(); //获取当前脚本的路径
log.info("baseDir="+baseDir);//打印出来
File file = new File(baseDir);//创建file对象
String strParentDirectory = file.getParent();//获取父目录
log.info("strParentDirectory="+strParentDirectory);//打印出来

byte[] result = prev.getResponseData(); //获取请求的返回
String fileName = "下载的文件.xlsx"; 
fileName = strParentDirectory +"/result/" + fileName; 
File file = new File(fileName);
file.delete();//先进行删除,避免文件存在报错
FileOutputStream out = new FileOutputStream(file);
out.write(result);

out.close();

注意:result目录应该已经存在

2.4 文件名称处理

  • 可以通过正则表达式,来获取响应头中的Content-Disposition内容,然后再使用split()方法,逐步提取文件名称
  • 要解析的请求头Content-Disposition示例如下:ContentDisposition:attachment;filename=AA31_VCU_ParseResult.xls
import java.io.*;
import org.apache.jmeter.services.FileServer;
import java.util.regex.*;

String baseDir=FileServer.getFileServer().getBaseDir(); //获取当前脚本的路径
//log.info("baseDir="+baseDir);//打印出来
String strParentDirectory = file.getParent();//获取父目录

byte[] result = prev.getResponseData(); //获取请求的返回体
String headers= prev.getResponseHeaders(); //获取返回的响应头
//log.info("###################"+headers); //jmeter console界面输出该信息

String pattern="Content-Disposition:(.*)";
Pattern r=Pattern.compile(pattern);//创建Pattern对象
Matcher m = r.matcher(headers);//创建matcher对象
String fileName = "template.xlsx";//默认的文件名称
if (m.find()){
    token=m.group(1).trim();
    String[] str = token.split(";");
    String a = str[1];
    String[] str1 = a.split("=");
//    log.info(str1[1]);
    fileName = URLDecoder.decode(str1[1], "UTF-8");
    log.info("fileName=" + fileName);
}else{
    log.info("No Match!");
}

fileName = strParentDirectory +"/result/" + fileName; 
File file = new File(fileName);
file.delete();//先进行删除,避免文件存在报错
FileOutputStream out = new FileOutputStream(file);
out.write(result);

out.close();

2.5 文件下载成功或失败判断

可添加以下代码对文件是否下载成功进行判断

if(file.exists()){
	//根据实际情况自己判断是否需要补充对导出文件的内容验证,此处暂时只判断文件是否存在
	prev.setResponseData("下载成功","UTF-8");
	//log.warn("下载成功");
}
else{
	prev.setResponseData("下载失败","UTF-8");
	//log.warn("下载失败");
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值