jmeter导入DB数据再再优化-创新互联

前言:分享和规定命名规范后,各位测试人员一致认为这样jmeter的jmx文件限制太死,主要体现六方面:

成都创新互联是网站建设技术企业,为成都企业提供专业的网站设计、成都网站制作,网站设计,网站制作,网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制适合企业的网站。十年品质,值得信赖!

第一:规定了一个jmx文件只能录入一个接口,这样会导致jmx文件很多

第二:导入DB的jmx文件每轮迭代都需要更换版本号,会带来额外的工作

第三:jmx文件严格要求了接口执行循序,会导致大家写好的用例会重新输出

第四:importDB的jmx文件与接口的jmx文件对应也会很多,不能一个importDB的jmx完成所有接口的工作

第五:删除了定义产品类型和页面类型字段,增加了接口类型字段

第六:测试反馈终端类型、版本号、接口类型不需要通过importDB 的jmx文件传入而是通过http请求名称按照一定规则去获取

因此针对上面四项不足,做了一些优化。

技术方面方面改变主要体现在:

第一:把终端类型、版本号、接口类型、接口名称、用例数目、用例成功数目、通过率这些字段,之前只有部分(接口类型、接口名称)是list结构,现在均改为list结构。
第二:java set操作的sql只有详细表,而统计表是通过sql操作的(通过select详细表计算出来统计表每个字段值insert和update的)
第三:联合唯一索引增加了一个字段creatTime,因为测试反应按照之前联合索引只能保留本轮迭代的数据,有之前的按照迭代保留数据,目前是按照当天保留数据(因此有之前精确到秒改为精确到日)

第四:SQL的各个字段获取规则进行了限制

jmeter线程请求命名规则:
由于代码做了字段获取的规则,循环到”终端、版本、类型、校验、接口”关键字时认为是本jmx文件需校验的接口和用例

终端类型获取规则:

由于代码做了终端类型获取的规则,截取”终端”和“版本”中间的字符作为终端类型

版本号获取规则:

由于代码做了版本号获取的规则,截取”终端”和“版本”中间的字符作为版本号

接口类型获取规则:
由于代码做了接口类型获取的规则,截取”终端”和“版本”中间的字符作为接口类型

接口名称获取规则:

由于代码做了接口名称获取的规则,截取”校验”和“接口”中间的字符作为接口名称

用例名称获取规则:

由于代码做了用例名称获取的规则,截取”接口”后面的字符作为接口名称

具体SQL key值的取值方法如下:

//获取符合规则的终端类型
     public static ArrayList  getTerminalType(String path) throws Exception{
             CsvUtil util = new CsvUtil(path);             int rowNum = util.getRowNum();
             String caseAllName = null;
             String TerminalType = null;
             ArrayList terminalTypeArray = new ArrayList();             for(int i=1;i  getVersion(String path) throws Exception{
             CsvUtil util = new CsvUtil(path);             int rowNum = util.getRowNum();
             String caseAllName = null;
             String version = null;
             ArrayList excVersionArray = new ArrayList();             for(int i=1;i  getInterfaceType(String path) throws Exception{
             CsvUtil util = new CsvUtil(path);             int rowNum = util.getRowNum();
             String caseAllName = null;
             String interfaceNameType = null;
             ArrayList interfaceTypeArray = new ArrayList();             for(int i=1;i  getInterfaceName(String path) throws Exception{
         CsvUtil util = new CsvUtil(path);         int rowNum = util.getRowNum();
         String caseAllName = null;
         String interfaceName = null;
         ArrayList interfaceNameArray = new ArrayList();             for(int i=1;i getCaseName(String path) throws Exception{
          CsvUtil util = new CsvUtil(path);         int rowNum = util.getRowNum();
         String caseAllName = null;
         String caseName = null;
         ArrayList caseNameArray = new ArrayList();         for(int i=1;i getcaseIsPass(String path) throws Exception{
        CsvUtil util = new CsvUtil(path);        int rowNum = util.getRowNum();
         ArrayList caseResultArray = new ArrayList();//         System.out.println(CaseNum);
         String caseAllName = null;         for(int i=1;i

支持和兼容:
第一:支持同个jmx文件多个接口用例场景
第二:兼容同个jmx文件虽同一个接口不同顺序的输入

一个要求:
jmeter命名规则为终端AAA版本BBB类型CCC校验DDD接口EEE

AAA为终端类型(如app、网站) ,BBB为迭代号(如9.0.1) ,CCC为接口类型(如搜索、跟团) ,DDD为接口名称(如默认出发城市),EEE为用例名称(如检验推荐城市否正确)

由于获取SQL每个字段均为List,因此若jmeter想使用,必须进行二次封装!!!

//封装上面获取终端类型、版本号、接口类型、接口名称、方法提供jmeter使用
     public static ArrayList getTerminalTypeArray(String path) throws Exception{
              ArrayList terminalTypeArray = readCsv.getTerminalType(path);                return terminalTypeArray;
        }     public static ArrayList getVersionArray(String path) throws Exception{
              ArrayList versionTypeArray = readCsv.getVersion(path);                return versionTypeArray;
        }     public static ArrayList getInterfaceTypeArray(String path) throws Exception{
              ArrayList interfaceTypeArray = readCsv.getInterfaceType(path);                return interfaceTypeArray;
        }      public static ArrayList getInterfaceNameArray(String path) throws Exception{
          ArrayList interfaceNameArray = readCsv.getInterfaceName(path);            return interfaceNameArray;
      }      public static ArrayList getCaseNameArray(String path) throws Exception{
              ArrayList caseNameArray = readCsv.getCaseName(path);                return caseNameArray;
          }      public static ArrayList getCaseIsPassArray(String path) throws Exception{
              ArrayList caseIsPassArray = readCsv.getcaseIsPass(path);                return caseIsPassArray;
          }

好了获取到了,我们做插入DB操作:

详细表跟之前改变不大!!(索引扩充一个createTime字段、时间有精确到秒改为精确到日)

如:

 public static String currTime(){
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
            String now = df.format(new Date());// new Date()为获取当前系统时间
            return now;
        }     //插入详细数据
     public static boolean insertDetailDB(String terminalType,String excVersion,String interfaceType,String interfaceName,String caseName,String excResult){          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 createTime = readCsv.currTime();
                String sql = "create table if NOT EXISTS AutoTest_DetailInterface(id int NOT NULL auto_increment primary key ,terminalType varchar(50) NOT  NULL DEFAULT 'App' ,"
                        + "excVersion varchar(50),interfaceType varchar(50) ,interfaceName varchar(50),"
                        + "caseName varchar(50) ,excResult varchar(50),creatTime varchar(50) NOT NULL DEFAULT '"+createTime+"',"
                                + " UNIQUE INDEX  ( terminalType,excVersion,interfaceType,interfaceName,caseName,creatTime ) )";  
//                System.out.println(sql);                // 创建数据库中的表,  
                int result = stmt.executeUpdate(sql);  
                if (result != -1) {  
                    sql = "insert into AutoTest_DetailInterface(terminalType,excVersion,interfaceType,interfaceName,caseName,excResult) values(?,?,?,?,?,?) "
                            + "ON DUPLICATE KEY UPDATE excResult=?";//                    sql = "insert into AutoTest_DetailInterface (permaryTitle,secondaryTitle,excVersion,excTerminal,excResult) 
//                    +values(primaryTitle,secordaryTitle,excVersion,excTerminal,excResult)";
                    st = conn.prepareStatement(sql);                    //存入终端类型转为小写
                    st.setString(1, terminalType.toLowerCase());
                    st.setString(2, excVersion);
                    st.setString(3, interfaceType);
                    st.setString(4, interfaceName);
                    st.setString(5, caseName);                    //存入执行结果true或者false转为小写
                    st.setString(6, excResult.toLowerCase());
                    st.setString(7, excResult.toLowerCase());
                    st.executeUpdate();
                    sql = "SELECT * FROM AutoTest_DetailInterface";  
                    System.out.println(stmt.executeQuery(sql));
                    ResultSet rs = stmt.executeQuery(sql);
                    System.out.println("id\tterminalType\texcVersion\tinterfaceType\tinterfaceName\tcaseName\texcResult\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)+ rs.getString(8));  
                    }  
                }  
                conn.close();  
                  
            } catch (Exception e) {  
                e.printStackTrace();  
                return false;
            }            return true;
     }

插入统计表:(相比之前思路都改变了~是通过详细表select计算统计后insert进去的而不是通过java依次获取每个字段值set进去的)

具体如下:

有一点说明:就是SQL在insert的时候若是insert整个sql的时候且当唯一联合索引键相同时,做更新不能用 key=vaule这种平常的用法(不然拿到第一行的数据更新了所有行的数据),而是 set key=VALUES(key)

具体用法可以看下http://www.jb51.net/article/39255.htm 这个用法,备注,因为这点纠结了我大半天时间!!!

//插入统计数据
     public static boolean insertTotalDB(){         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 createTime = readCsv.currTime();
                String sql = "create table if NOT EXISTS AutoTest_TotalInterface(id int NOT NULL auto_increment primary key ,terminalType varchar(50) NOT  NULL DEFAULT 'App' ,"
                        + "excVersion varchar(50),interfaceType varchar(50) ,interfaceName varchar(50),"
                        + "caseTotalNum int,caseSucNum int,excRate varchar(50) ,creatTime varchar(50) NOT NULL DEFAULT '"+createTime+"',"
                                + " UNIQUE INDEX  ( terminalType,excVersion,interfaceType,interfaceName,creatTime ) )"; 
                // 创建数据库中的表,  
                int result = stmt.executeUpdate(sql);  
                if (result != -1) {  
                    String selectSQL = "SELECT  terminalType,excVersion,interfaceType,"
                            + "interfaceName,caseTotalNum,caseSucNum,"
                            + "ROUND(caseSucNum/caseTotalNum,3) "
                            + "as excRate,creatTime from("
                            + "SELECT terminalType,excVersion,interfaceType,interfaceName,count(1) "
                            + "as caseTotalNum,sum(ex) as caseSucNum,creatTime from("
                            + "SELECT terminalType,excVersion,interfaceType,interfaceName,"
                            + "creatTime,case excResult "
                            + "when 'true' then 1 when 'false' then 0 end as ex from "
                            + "AutoTest_DetailInterface)m group by "
                            + "terminalType,excVersion,interfaceType,interfaceName,creatTime)n";
                     sql = "insert into AutoTest_TotalInterface("
                                + "terminalType,excVersion,interfaceType,interfaceName,caseTotalNum,caseSucNum,"
                                + "excRate,creatTime) "+selectSQL+" ON DUPLICATE KEY UPDATE caseTotalNum=VALUES(caseTotalNum),caseSucNum=VALUES(caseSucNum),excRate=VALUES(excRate)";
                        System.out.println(sql);                        //执行插入操作
                        st = conn.prepareStatement(sql);
                        st.executeUpdate();
                        sql = "SELECT * FROM AutoTest_TotalInterface";  
                        System.out.println(stmt.executeQuery(sql));
                     ResultSet rs = stmt.executeQuery(sql);                     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) + rs.getString(9) );  
                    }  
                }  
                conn.close();  
                  
            } catch (Exception e) {  
                e.printStackTrace();  
                return false;
            }            return true;
    }

好了,到此结束,当然,importDB的jmx文件也要发生变化(直接调用方法即可),具体如下:

import readDB.*;import excFile.*;


String path = "D:\\excResult.csv";int length = readCsv.getTerminalTypeArray(path).size();
log.info("用例数量为:"+length);//循环获取各个参数for(int i=0;i

导入DB数据如下:

原始数据:

导入详细表的数据:

导入统计表数据:

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网页名称:jmeter导入DB数据再再优化-创新互联
当前地址:http://scyanting.com/article/ijohg.html