Jmeter读取执行Case插入DB生成报表和备份记录

发表于:2017-4-24 11:20

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:niuzhigang    来源:博客园

  前言:由于通过jmeter写的接口自动化木有数据导入和统计分析功能,因此做了二次开发,目的是读取每条case获取接口名称和用例名称,通过获取的case执行结果进行计算,得到详细接口的用例通过率存入DB,并解析出每条case的执行结果存入DB。
  流程图如下:
  由于包含case的详细数据和接口的统计数据,因此目前暂定2张表。
  具体表结构如下:
  接口统计表:
  用例执行结果详细表:
  首先就是如何让jmeter生成一定格式的csv文件。那么问题一:如何把执行结果生成CSV文件?问题二如何生成一定格式的CSV文件?
  解决方案问题一:
  在"察看结果树"监听器加入存储路径(在文件名写入 路径+文件名):如:
  执行jmx文件后会生成一个excResult.csv文件。如:
  解决方案步骤二:
  满足一定格式就是满足如下格式:
  那么如何满足此格式呢?
  在jmeter的"察看结果树"监听器Configure配置下取消掉"Save As XML"
  好了,到此初步的要求已经达到。
  剩下的就是开发脚本,如何读取csv文件并插入DB
  代码部分就不上传了,有兴趣的同学可以私聊
  上传下如何插入DB吧、数据统计吧
  数据统计代码如下:
public static int getSucNum(String path) throws Exception{
CsvUtil util = new CsvUtil(path);
int rowNum = util.getRowNum();
int caseNum = rowNum -1;
int sucNum = 0;
List list = new ArrayList();
for(int i=1;i<rowNum;i++){
String caseName = util.getString(i, 2);
String result = util.getString(i, 7);
list.add(caseName);
list.add(result);
if(result.equals("true")==true){
sucNum +=1;
}
}
return sucNum ;
}
//计算百分比
public static  String percent(int sucCaseNum, int allCseNum){
// 创建一个数值格式化对象
NumberFormat numberFormat = NumberFormat.getInstance();
// 设置精确到小数点后2位
numberFormat.setMaximumFractionDigits(2);
String result = numberFormat.format((float) sucCaseNum / (float) allCseNum * 100);
return result;
}
public static String  getPryKey(String path) throws Exception{
CsvUtil util = new CsvUtil(path);
String secTitle = util.getString(1, 2);
//            System.out.println("获取检查的接口名称:"+secTitle);
String subTitle = secTitle.substring(2, secTitle.length());
//            System.out.println("获取接口名称:"+subTitle);
return subTitle;
}
//获取插入DB的接口执行结果(通过率)
public static String  getExcRate(String path) throws Exception{
CsvUtil util = new CsvUtil(path);
int rowNum = util.getRowNum();
int caseNum = rowNum -1;
int sucNum = 0;
for(int i=1;i<rowNum;i++){
String caseResult = util.getString(i, 7);
//                System.out.println("用例执行结果为:" + caseResult);
if(caseResult.equals("true")==true){
sucNum +=1;
}
}
String caseRate = CsvUtil.percent(sucNum, caseNum)+"%";
//            System.out.println("用例通过率为:"+caseRate);
return caseRate;
}
//获取插入DB的secordaryTitle&excResult(用例名称)&(true or false)
public static void  getSecKey(String path) throws Exception{
CsvUtil util = new CsvUtil(path);
int rowNum = util.getRowNum();
String caseName = null;
for(int i=1;i<rowNum;i++){
caseName = util.getString(i, 2);
//                System.out.println("用例名称为:"+caseName);
String caseResult = util.getString(i, 7);
//                System.out.println("用例执行结果为:" + caseResult);
}
}
  插入DB的代码:
//插入统计数据
public static boolean insertTotalDB(String primaryTitle,String excVersion,String excTerminal,String excRate,int caseTotalNum,int caseSucNum){
try {
Class.forName("com.mysql.jdbc.Driver");
String databaseName = "test";// 已经在MySQL数据库中创建好的数据库。
String userName = "mobtest";// MySQL默认的root账户名
String password = "tuniu520";// 默认的root账户密码为空
String connUrl = "jdbc:mysql://10.10.30.200:3306/";//连接地址
Connection conn = DriverManager.getConnection(connUrl + databaseName, userName, password);
PreparedStatement st = null;
Statement stmt = conn.createStatement();
String sql = "create table if NOT EXISTS AutoTest_TotalInterface(id int NOT NULL auto_increment primary key ,permaryTitle varchar(255) ,excVersion varchar(255),excTerminal varchar(255) NOT  NULL DEFAULT 'App' ,excRate varchar(255) ,caseTotalNum int,caseSucNum int,creatTime timestamp NULL DEFAULT CURRENT_TIMESTAMP )";
// 创建数据库中的表,
int result = stmt.executeUpdate(sql);
if (result != -1) {
sql = "insert into AutoTest_TotalInterface(permaryTitle,excVersion,excTerminal,excRate,caseTotalNum,caseSucNum) values(?,?,?,?,?,?)";
st = conn.prepareStatement(sql);
st.setString(1, primaryTitle);
st.setString(2, excVersion);
st.setString(3, excTerminal);
st.setString(4, excRate);
st.setInt(5, caseTotalNum);
st.setInt(6, caseSucNum);
st.executeUpdate();
sql = "SELECT * FROM AutoTest_TotalInterface";
System.out.println(stmt.executeQuery(sql));
ResultSet rs = stmt.executeQuery(sql);
System.out.println("id\tprimaryTitle\tsexcVersion\texcTerminal\texcRate\tcaseTotalNum\tcaseSucNum\tcreatTime");
while (rs.next()) {
System.out.println(rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString(3) + "\t" + rs.getString(4) + "\t" + rs.getString(5) + "\t" + rs.getString(6) + "\t" + rs.getString(7)+ "\t" + rs.getString(8));
}
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
  有2点说明:读取csv文件乱码问题和读取关闭文件(因为结束后会有备份历史记录,因此必须关闭CSV文件)
  乱码问题解决方案不要用FileReader而是InputStreamReader可以指定读取编码
public CsvUtil(String fileName) throws Exception {
this.fileName = fileName;
//FileReader可能会根据不同的环境造成从CSV读取时乱码
br = new BufferedReader(new FileReader(fileName));
//解决乱码
br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"utf-8"));
String stemp;
while ((stemp = br.readLine()) != null) {
list.add(stemp);
}
//关闭csv文件
br.close();
}
  代码开发基本完成,就差数据备份了,数据备份的代码如下:
package excFile;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class renFile {
public static boolean renameFile(String path,String oldname,String newname){
File file=new File(path+oldname);
if(file.exists())
{
file.renameTo(new File(path+newname));
return true;
}
return false;
}
public static String currTime(){
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
String now = df.format(new Date());// new Date()为获取当前系统时间
return now;
}
public static void main(String[] args) {
String path = "d:\\";
String oldname = "excResult.csv";
String newname = "excResult"+renFile.currTime()+".csv";
System.out.println("获取当前时间:"+renFile.currTime());
System.out.println("获取最新的名称:"+renFile.renameFile(path, oldname, newname));
}
}
  恭喜,代码开发基本结束,那么如何被jmeter引用?
  把开发的代码export为jar包
  如导出jar包名为excDB.jar
  由于插入DB要有jdbc依赖包。(mysql-jdbc.jar)
  导出后,把2个jar放到jmeter的lib/ext目录下,重启jmeter 即可引用。
  如下:在jmeter的beanshell(取样器)工具中写入调用函数脚本即可
import readDB.*;
import excFile.*;
String excVersion = "9.1.2";
String excTerminal = "App";
String path = "D:\\excResult.csv";
String primaryTitle = CsvUtil.getPryKey(path);
log.info("获取接口名称:"+primaryTitle);
String excRate = CsvUtil.getExcRate(path);
log.info("获取单个接口用例通过率:"+excRate);
CsvUtil util = new CsvUtil(path);
int rowNum = util.getRowNum();
//log.info("获取行数:"+rowNum);
int caseTotalNum = rowNum -1;
log.info("获取用例总数:"+caseTotalNum);
int caseSucNum = CsvUtil.getSucNum(path);
log.info("获取用例通过数量:"+caseSucNum);
for(int i=1;i<rowNum;i++){
String secordaryTitle = util.getString(i, 2);
log.info("获取用例名称:"+secordaryTitle);
String excResult = util.getString(i, 7);
log.info("获取用例执行结果:"+excResult);
//执行insertDB---详细数据
CsvUtil.insertDetailDB(primaryTitle, secordaryTitle, excVersion, excTerminal, excResult);
}
////执行insertDB---统计数据
CsvUtil.insertTotalDB(primaryTitle, excVersion, excTerminal, excRate, caseTotalNum, caseSucNum);
String dir = "d:\\";
String oldname = "excResult.csv";
log.info("获取最新文件名称:"+renFile.currTime());
String newname = "excResult"+renFile.currTime()+".csv";
log.info("获取最新文件名称:"+newname);
renFile.renameFile(dir, oldname, newname);
  大致截图如下:
  导入DB的jmx文件脚本有几个变量强调下:
  ①excVersion---版本号(如9.1.0)
  ②excTerminal---终端类型(如App、网站、M站)
  ③path---csv文件路径(如d:\excResult.csv)
  ④dir---csv在哪个目录下(如d:\)
  ⑤oldname---csv文件名(如excResult.csv)
  其中import这2个包名要准确,就是你在开发这些class文件时创建的包名
  import readDB.*;
  import excFile.*;
  如:
  这样会把存入DB的jmx文件和用例的jmx文件放在一个文件夹下执行,执行循序会根据jmx文件修改时间的正序来执行,因此一定要确保执行case的jmx文件时间要在导入DB的jmx文件前面。
  当然也可以把所有按照接口生成的的jmx文件和分别导入DB的jmx文件放在一个文件夹下,但必须渠道入到的CSV文件名不相同,每个对应读取CSV导入DB的jmx文件的指向路径也不同。
  基本完成,执行结果就如上面的导入DB的数据一样。
  这样整个开发到此结束!!!
  还有就是接口名称和用例名称命名规范的问题!
  有2个要求:
  第一个要求:由于代码做了接口名称获取的规则,是获取第一条接口case名称但不是单纯的获取,是截断了前面2个字符,后面所有字符作为接口名称。
  因此要求case输出者在输出接口自动化时第一条case名称命名为“校验XXXX接口”!!这样根据截断规存入DB的接口名称为“XXXX接口”,才符合接口名称命名规范。
  第二个要求:jmx文件,一个接口自动化场景输出一个jmx文件,不要在此jmx文件上输出其它的接口case,在这个接口的基础上输出不同场景的case。
  否则会把不同接口统计到一个接口中去!
  备份的历史记录文件如下:(原文件名+时间戳)。
  为什么要renName?
  一方面:也是renName的根本原因,因为每次执行的CSV文件,如果在执行接口自动化的jmx文件前不删除,就会把本次的执行结果追加到原csv文件!!!
  另一方面:保存历史记录。
  最后也就是视图的展现,数据已存入DB,接下来就是读取数据制图即可!
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号