在实际的接口测试中,有时需要根据情况进行文件的上传和下载。在文件数量比较小的时候,我们当然可以直接处理(比如若干个接口都用一个文件)。但是,如果我们上传的文件需要使用不同文件夹里不同的文件,而且数量又比较大的情况下,直接写路径就比较麻烦了。

  那么,怎样来处理这样的问题呢?还是需要先整理一下思路。

  首先,我们需要根据某些特征,找到这些文件。例如,我们可以在指定的文件夹下面,按照文件后缀名来找寻文件。通常,我们在DOS下查询该文件夹下寻找同一后缀名文件的时候,会使用通配符“*”来代替文件名,例如:*.jpg,*.xls等等。那么,我们可以指定一个文件夹,然后使用将通配符变为正则的方式,来匹配查找文件。

  另外,如果在我们指定的文件夹中,存在子文件夹的情况,我们需要进行递归处理。即,进入子文件夹后,再次对子文件夹下的对象进行遍历,以此类推。

先来看一段代码:

    private static String generatePattern(String fileConf) {
fileConf = fileConf.trim();
// 根据配置生成正确的正则
fileConf = fileConf.replace('*', '#');
// 将*号之前加上.
fileConf = fileConf.replaceAll("#", ".*");
return fileConf;
}

  这里,我们定义了一个生成正则的方法。就是将"*.XXX"变成“.*.XXX”(仔细看,就是在之前加了一个".")。我们可以利用这个正则表达式来匹配我们想要寻找的文件。

  接下来,我们来看一下递归查找的问题。首先,我们需要定义一个要查找的文件夹。而在java中,我们可以直接定义一个主路径作为file的对象。

例如:

        String c = "k:/abc/";
File file = new File(c);

这样的话,可以使用getName()方法获取文件或文件夹的名称(不包含上级路径)。另外,也可以使用listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。当然,对于文件,这样操作会返回null。

下面,我们来看一下递归的操作。思路是这样的:

1.判断当前的file对象是文件还是文件夹

2.如果是文件,若匹配正则,则将文件加入list。

3.如果是文件夹,则获取该文件夹下面所有的文件或者目录对象,若匹配正则,则将文件加入list。

    private static ArrayList<File> filePattern(File file, Pattern p) {
if (file == null) {
return null;
}
// 如果是文件,则加入fileList
if (file.isFile()) {
Matcher fMatcher = p.matcher(file.getName());
if (fMatcher.matches()) {
ArrayList<File> list = new ArrayList<File>();
list.add(file);
return list;
}
// 如果是目录,则进行递归查找
} else if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null && files.length > 0) {
ArrayList<File> list = new ArrayList<File>();
for (File f : files) {
//此处进行递归
ArrayList<File> rlist = filePattern(f, p);
if (rlist != null) {
//将查找结果都加入fileList
list.addAll(rlist);
}
}
return list;
}
}
return null;
}

  那么,根据上面的代码,我们可以将路径下所有的匹配正则的文件都找到,并放入fileList中。

  接下来,我们来定义一个方法,使用主路径以及通配符作为参数,来进行文件的查找。在通配符参数的指定中,我们使用“;”来进行分隔,来找到我们所需要的文件。

例如:

String dirs = "k:/abc/";
String file_con = "*.doc;*.xls";

  这里会出现一个新的问题,如果我按照上面所写,会把“k:/abc/”下的所有匹配的文件都找出来。

  假如,我是需要寻找主路经下test1文件夹下的*.doc,和test2文件夹下的*.xls怎么办?

  这里在指定参数的部分,我们需要对文件夹作出判断,即对最后一个“/”进行分隔处理。

请看下面一段代码:

    public static List<File> getFilesByConf(String dir, String fileConf) {
String[] fileConfArr = fileConf.split(";");// 多个配置‘;’分开
List<File> list = new ArrayList<File>();
if (fileConfArr != null && fileConfArr.length > 0) {
for (String conftemp : fileConfArr) {
int at = conftemp.lastIndexOf("/");
File file = null;
String fileContextPath = "";
// 绝对目录路径
String contextPath = dir;
// 针对目录部分的处理
if (at > 0) {
fileContextPath = fileConf.substring(0, at);
}
if (StringUtil.isNotEmpty(fileContextPath)) {
contextPath = contextPath + fileContextPath;
}
file = new File(contextPath);
String fileNameConf = conftemp.substring(at + 1,conftemp.length());// 文件名配置
String fileConfTemp = generatePattern(fileNameConf);
Pattern p = Pattern.compile(fileConfTemp);
ArrayList<File> listtemp = filePattern(file, p);
list.addAll(listtemp);
}
}
return removeDuplicate(list);// 去重
}

  这里,我们就完成了针对路径的处理。顺便说一下,这里的去重,使用的是利用HashSet的特性来进行去重。

    public static List removeDuplicate(List list) {
if (list == null) {
return null;
}
Set set = new HashSet();
List newList = new ArrayList();
for (Iterator iter = list.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (set.add(obj)) {
newList.add(obj);
}
}
return newList;
}

  至此,我们就完成了对于文件查找的处理。

  总结一下,我们只需要提供两个参数,一个是主路经,一个匹配的通配符的字符串参数(可以带路径),即可批量查找到我们所需要的文件。

  

  接下来,我们看一下,下载文件的处理。

  下载文件一般比较好处理,基本思路就是使用输入流来写入,然后保存即可。

  需要注意的是,针对比较大的文件时,我们需要设置Buffer(即缓冲区)。不应用缓冲区的时候,每次读取一个字节,写入一个字节,由于操作磁盘比内存慢的很多,所以不应用缓冲区效率很低;应用缓冲区,可以一次读取多个字节,先不写入磁盘,而是放入内存之中,到了缓冲区大小的时候,在写入磁盘,减少了对磁盘的操作,效率较高。

public static boolean writeFile(InputStream is, String filePath) {
File file = new File(filePath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
FileOutputStream fileout;
try {
fileout = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
/**
* 根据实际运行效果 设置缓冲区大小
*/
byte[] buffer = new byte[10 * 1024];
int ch = 0;
try {
while ((ch = is.read(buffer)) != -1) {
fileout.write(buffer, 0, ch);
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
try {
is.close();
fileout.flush();
fileout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

  这里根据实际情况,来设置缓冲区的大小。

  这样就可以根据接口返回的内容,写入文件到指定的路径中。

基于Java+HttpClient+TestNG的接口自动化测试框架(八)------ 针对文件的处理的更多相关文章

  1. 基于Java+HttpClient+TestNG的接口自动化测试框架(四)-------参数存取处理

    在真正开始接口测试之前,我们需要对参数的处理进行梳理.这里所说的“参数”,既包含之前在xml中的配置(我们称之为全局参数),也包含在每一条用例中书写的param.全局参数为固定不变的,而根据接口相应获 ...

  2. Python 基于python实现的http接口自动化测试框架(含源码)

    基于python实现的http+json协议接口自动化测试框架(含源码) by:授客 QQ:1033553122      欢迎加入软件性能测试交流 QQ群:7156436  由于篇幅问题,采用百度网 ...

  3. 手把手教你用Eclipse+TestNG搭建接口自动化测试框架

    转载于:http://qa.blog.163.com/blog/static/190147002201510275306185/ 把群博里关于接口自动化的文章都看了一遍,都是关于测试过程中遇到的问题及 ...

  4. Eclipse+TestNG搭建接口自动化测试框架

    一.环境安装 1.前提 安装好jdk 配置好Java环境变量 安装Eclips 这些网上都有,就不再详细介绍. 资源分享链接:http://pan.baidu.com/s/1v9Fw6 2.安装Tes ...

  5. 基于Python + requests 的web接口自动化测试框架

    之前采用JMeter进行接口测试,每次给带新人进行培训比较麻烦,干脆用python实现,将代码和用例分离,易于维护. 项目背景 公司的软件采用B/S架构,进行数据存储.分析.管理 工具选择 pytho ...

  6. 接口自动化 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)

    基于python实现的http+json协议接口自动化测试框架(实用改进版)   by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436     目录 1.      ...

  7. Python 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)

    目录 1.      写在前面 2.      开发环境 3.      大致流程 4.      框架简介 5.      运行结果展示 6.      文件与配置 7.      测试接口实例 n ...

  8. 接口自动化测试框架 -- reudom

    reudom Automated testing framework based on requests and unittest interface. 基于 Unittest 和 Requests ...

  9. 基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport的接口自动化测试框架

    接口自动化框架 项目说明 本框架是一套基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport而设计的数据驱动接口自动化测试框架,TestNG ...

随机推荐

  1. 纪中17日T1 2321. 方程

    纪中17日T1 2321. 方程 (File IO): input:cti.in output:cti.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制   Goto ...

  2. P1553 数字反转(升级版)(copy(),reverse(),find(),substr(),erase())

    题目描述 给定一个数,请将该数各个位上数字反转得到一个新数. 这次与 NOIp2011 普及组第一题不同的是:这个数可以是小数,分数,百分数,整数.整数反转是将所有数位对调:小数反转是把整数部分的数反 ...

  3. git需要设置再次弹出输入账号密码

    今天在用命令行pull线上代码到本地时遇到一个尴尬的问题,因为新下载的git貌似默认了在pull,push代码时只弹出一次输入账号密码,反正我这里是这样的. 开始在pull线上代码的时候不小心密码输错 ...

  4. 关于Spring注入参数到static静态参数失败问题处理。解决Autowired annotation is not supported on static fields的问题

    直接贴代码 把注入参数的注解加到set方法上面去即可. 因为这是一个工具类用到的config,所以一开始没有加@Component,还是依然为空,加上之后就正常能注入了

  5. pandas学习笔记之删除指定列

    删除指定 def df["列名"] del df4["韩国地震影响"] 直接删除,df4中不在含有"韩国地震影响"这一列了 drop 不改变 ...

  6. 曼孚科技:AI算法领域常用的39个术语(下)

    算法是人工智能(AI)核心领域之一. 本文整理了算法领域常用的39个术语,希望可以帮助大家更好地理解这门学科. 本文为下半部分,上半部分见本账号上一篇文章. 19.迁移学习(Transfer Lear ...

  7. JavaDay10(下)

    生产者消费者问题 问题描述 有两个进程:一组生产者进程和一组消费者进程共享一个初始为空.固定大小为n的缓存(缓冲区).生产者的工作是制造一段数据,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必 ...

  8. Linux 宝塔面板忘记密码的解决方案

    进入ssh 输入以下命令重置密码(把命令最后面的   “testpasswd”  替换成你要改的新密码)注:若是debian/ubuntu用户,请使用有root权限的账户去执行这条命令 cd /www ...

  9. 04-SV连接设计和测试平台

    1.验证一个设计的步骤: 生成输入激励,捕捉输出响应,决定对错和进度 2.连接设计和测试平台 信号连接:SystemVerilog已经扩展了传统的reg类型,可以像wire那样用来连接模块,它的新名字 ...

  10. 微信小程序调起支付API

    官方文档: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7 https://developers.weixin.q ...