前言:
上一篇 接口自动化 -- 基于JMeter的实战攻略(3) 我们已经完成了接口文档读取、执行的操作,现在我们要做的就是输出接口执行结果了。
准备:
1、封装 CSV 工具 jar
基于 openCsv 进行操作,具体可参考其官网:http://opencsv.sourceforge.net/
项目架构:
①、编写实体类 TestCaseData
package com.xcj.bean;
import com.opencsv.bean.CsvBindByPosition;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestCaseData {
//接口编号
@CsvBindByPosition(position = 0)
private String interfaceNo;
//接口域名、IP
@CsvBindByPosition(position = 1)
private String interfaceIP;
//接口端口
@CsvBindByPosition(position = 2)
private String interfacePort;
// 接口地址
@CsvBindByPosition(position = 3)
private String interfaceAddress;
//用例编号
@CsvBindByPosition(position = 4)
private String caseNo;
//用例名称
@CsvBindByPosition(position = 5)
private String caseName;
//接口类型
@CsvBindByPosition(position = 6)
private String interfaceType;
//头部参数
@CsvBindByPosition(position = 7)
private String headers;
//测试数据
@CsvBindByPosition(position = 8)
private String testData;
//关联数据,用于接口数据关联传递
@CsvBindByPosition(position = 9)
private String associatedData;
//预期结果
@CsvBindByPosition(position = 10)
private String expectedResults;
//实际结果
@CsvBindByPosition(position = 11)
private String actualResults;
//是否验证sql
@CsvBindByPosition(position = 12)
private String ifVerifySql;
//执行sql
@CsvBindByPosition(position = 13)
private String executeSql;
//预期sql结果
@CsvBindByPosition(position = 14)
private String expectedSqlResults;
//实际sql结果
@CsvBindByPosition(position = 15)
private String actualSqlResults;
//用例状态
@CsvBindByPosition(position = 16)
private String caseStatus;
//执行人
@CsvBindByPosition(position = 17)
private String expecteMan;
//执行时间
@CsvBindByPosition(position = 18)
private String executionTime;
//备注
@CsvBindByPosition(position = 19)
private String remarks;
}
②、编写 CSVUtils 工具类
package com.xcj.service;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.opencsv.exceptions.CsvDataTypeMismatchException;
import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
import com.xcj.bean.TestCaseData;
import java.io.*;
import java.util.List;
public class CSVUtils {
/**
* 读取csv文件内容成bean实体类
*
* @param filePath csv文件路径
* @param ignoreFirstLine 忽略首行
* @param number 读取行数
* @return
* @throws FileNotFoundException
*/
public TestCaseData readCsv(String filePath, boolean ignoreFirstLine, int number) throws FileNotFoundException, UnsupportedEncodingException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8"));
List<TestCaseData> beans = new CsvToBeanBuilder(bufferedReader).withSkipLines(1)
.withType(TestCaseData.class).build().parse();
return beans.get(number);
}
/**
* @param filePath 预写入内容的文件路径
* @param data 文件内容
* @throws IOException
* @throws CsvRequiredFieldEmptyException
* @throws CsvDataTypeMismatchException
*/
public void writeCsv(String filePath, TestCaseData data) throws CsvDataTypeMismatchException, CsvRequiredFieldEmptyException, IOException {
try(Writer writer = new FileWriter(filePath, true)){
StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer).build();
beanToCsv.setOrderedResults(true);
//判断文件为空时,添加首行
File file = new File(filePath);
if (file == null || file.length() == 0 || !file.exists()) {
beanToCsv.write(new TestCaseData("接口编号", "域名/IP", "端口", "接口地址", "用例编号", "用例名称"
, "接口类型", "headers", "测试数据", "关联数据", "预期结果", "实际结果"
, "是否验证sql", "执行sql", "预期sql结果", "实际sql结果", "用例状态"
, "执行人", "执行时间", "备注"));
}
beanToCsv.write(data);
}
}
}
③、打包成工具 jar
分享一个我打包好的jar资源:
https://cdn.yiduoyun.space/JMeter%E5%AE%9E%E6%88%98%E7%B3%BB%E5%88%97/ext/csv_tool-1.0-SNAPSHOT-jar-with-dependencies.jar
2、应用 CSV 工具 jar
将 jar 包放入 jmeter 安装目录下的 lib/ext 目录下,重启 jmeter 后生效。
3、BeanShell 监听器(输出文件)
下面代码中,需要我们写文件的读写文件路径 readFilePath 和 writeFilePath ,具体值可按各自的需求修改。
import com.xcj.bean.TestCaseData;
import com.xcj.service.CSVUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
log.info("最终BeanShell 监听器:后置处理器执行,testCaseStatus的状态为:"+props.get("testCaseStatus"));
if(vars.get("testCaseStatus") == "end"){
//测试模板的路径
String readFilePath = "C:/Users/lx/Desktop/接口测试用例模板.csv";
//输出测试结果的路径
String writeFilePath = "C:/Users/lx/Desktop/接口报告"+ new SimpleDateFormat("yyyyMMdd").format(new Date().getTime()) +".csv";
CSVUtils csvUtils = new CSVUtils();
TestCaseData testCaseData = null;
int interfaceNo = Integer.parseInt(vars.get("interfaceNo"));
//log.info("interfaceNo == "+interfaceNo);
log.info("最终BeanShell 监听器:ctx.getThreadNum()=="+ctx.getThreadNum());
try
{
//自己通过opencsv封装的工具类,readCsv(param1,param2,param3),第一个参数为读取模板的路径,第二个参数为是否忽略第一行,第三个参数为读取行数(0开始)
testCaseData = csvUtils.readCsv(readFilePath, true, ctx.getThreadNum());
log.info("最终BeanShell 监听器:"+testCaseData.toString());
//写入测试结果
testCaseData.setActualResults(props.get("responseResult"));
testCaseData.setActualSqlResults(vars.get("dbData"));
log.info("最终BeanShell 监听器:props.get(flag) : "+ props.get("flag"));
testCaseData.setCaseStatus(props.get("flag")?"测试通过":"测试未通过");
testCaseData.setExpecteMan("JMeter 自动化测试");
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime());
testCaseData.setExecutionTime(format);
try
{
//自己通过opencsv封装的工具类,writeCsv(param1,param2),第一个参数表示输出文件的路径,第二个表示数据bean实体类
csvUtils.writeCsv(writeFilePath, testCaseData);
log.info("最终BeanShell 监听器:写入测试用例成功!");
}
catch(CsvDataTypeMismatchException e)
{
log.error("最终BeanShell 监听器:CsvDataTypeMismatchException");
e.printStackTrace();
}
catch(CsvRequiredFieldEmptyException e)
{
log.error("最终BeanShell 监听器:CsvRequiredFieldEmptyException");
e.printStackTrace();
}
catch(IOException e)
{
log.error("最终BeanShell 监听器:IOException");
e.printStackTrace();
}
}
catch(FileNotFoundException e)
{
log.error("最终BeanShell 监听器:FileNotFoundException");
e.printStackTrace();
}
catch(UnsupportedEncodingException e)
{
log.error("最终BeanShell 监听器:UnsupportedEncodingException");
e.printStackTrace();
}
finally
{
vars.remove("testCaseStatus");
}
}
4、添加聚合报告(可选)
使用 jmeter 可视化工具执行的话,可添加聚合报告来输出 .jtl 文件,方便后续输出 html 测试报告。如若使用指令执行 .jmx 文件,就可以不加这个了,直接在指令中加 -l 文件名.jtl -e -o 生成后的路径 即可。
总结:
至此,jmeter自动化脚本文件的编写就完成了,下一篇我们将结合 git、maven、jenkins 把这套方案跑起来。
最后附上完整的 .jmx 文件下载路径:https://cdn.yiduoyun.space/JMeter%E5%AE%9E%E6%88%98%E7%B3%BB%E5%88%97/%E6%A8%A1%E6%9D%BF.jmx
评论区