美文网首页JMeter学习笔记
JMeter 判断字符串是否存在该集合(List 或数组)

JMeter 判断字符串是否存在该集合(List 或数组)

作者: DC_ing | 来源:发表于2017-12-23 20:19 被阅读269次

    在学习 JMeter 的 JDBC 模块中,遇到了 ArrayList 和 String 的之间需要对比的问题,折腾我一周时间了。这个问题如果用代码解决的话,一个 for 循环就能搞掂,但在 JMeter 中就比较麻烦了。因为在 JMeter 界面上,一定得数字或字符串,才能进行对比,其他类型是不能对比的。以下的2种解决方案是分别使用 BeanShell 和函数解决的。

    问题:

    如何在 JMeter 中判断字符串是否在集合(List)或数组里面?集合和数组的大小不定,匹配的字符串位置也不定或者没有。

    例子:

    在测试前,我们需要在一个数据表(table)准备一些测试数据,但如果这个表已存在,那就无需创建了,直接对表进行修改,增减数据即可。

    问题分析:

    首先,我们不知道整个数据库的表有多少个?也不知道我们要创建的数据表是否存在,如果存在,那在哪个位置呢?那怎么完成ArrayList 和 String的对比呢,使用JMeter 组件还是代码解决?

    初步解决方案:

    先使用SHOW TABLES;查询数据库所有数据表,将每一个表的名称分解成一个字符串,这样比较就容易多了。

    BeanShell 解决方案

    1、查询当前数据库的表

    在 JMeter 创建一个 JDBC Request,查询数据库当前所有的表名,并将其保存到tables这个变量中。

    JDBC Request.png

    2、添加 BeanShell 后置处理器,使用代码进行比较

    对上述的 JDBC Request 添加一个 BeanShell 的后置处理器,进行代码处理,最后对isTableExist变量进行判断即可(true 为表已创建,false 为表未创建)。

    BeanShell PostProcessor.png

    一并贴上 BeanShell 代码

    //将数据库的表名与创建的表名一一比较,如存在,不创建,如不存在,则创建数据表
    
    //获取当前数据库的表数目
    int tablesNum = Integer.parseInt(vars.get("tables_#"));
    //默认为 false
    boolean isTableExist = false;
    log.info("数据表数目:" + tablesNum.toString());
    if(tablesNum != 0) {
        String buildTable = vars.get("testTable");
        //对整个数据库的表名与需创建的表名一一比较
        for(int i=1; i<=tablesNum; i++) {
            String table = vars.get("tables_"+i);
            //如果数据库存在该表,则为 true
            if(buildTable.equals(table)) {
                isTableExist = true;
            }
        }
    }
    String isExist = Boolean.toString(isTableExist);
    //isTableExist 是false,则需创建,如为 true,则无需创建
    vars.put("isTableExist",isExist);
    log.info("【" + vars.get("testTable") + "】数据表是否存在数据库中:" + isExist);
    

    3、调用isTableExist

    在创建数据表时,可根据isTableExist的值来判断是否需要创建表。可在 If Controler 控制器上使用,如下图所示:

    if_Controler.png

    函数解决方案

    这个解决方案其实就是将上述代码整理成一个函数,这样在 JMeter 调用就方便多了,不用每次都需要复制编写 BeanShell 代码,增加错误率,使用也更便捷一些。

    1、查询当前数据库的表,并将表的结果保存到变量中

    第一步与 BeanShell 解决方案大同小异,主要是保存的变量不一样而已。当然也可以跟第一步一样,只不过需要函数做出相应的改动,这一块就留给大家练练手。

    JDBC Request2.png

    2、编写函数

    编写函数的过程就不在这里赘述了,大家对 JMeter 函数开发不熟悉的话,可以百度一下,资料大把。
    按照惯例,还是贴上代码给大家吧。

    package com.dc.functions.functions;
    
    import org.apache.jmeter.engine.util.CompoundVariable;
    import org.apache.jmeter.functions.AbstractFunction;
    import org.apache.jmeter.functions.InvalidVariableException;
    import org.apache.jmeter.samplers.SampleResult;
    import org.apache.jmeter.samplers.Sampler;
    import org.apache.jmeter.threads.JMeterVariables;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.*;
    
    public class FindTableInDataBase extends AbstractFunction {
    
        private static final Logger log = LoggerFactory.getLogger(FindTableInDataBase.class);
        //显示的参数名字
        private static final List<String> desc = new LinkedList<>();
        static {
            desc.add("DataBase Result Variable Name");
            desc.add("DataBase Name");
            desc.add("Table Name");
        }
        //显示的函数名字
        private static final String KEY = "__FindTableInDataBase";
        //参数值
        private Object[] values;
    
        @Override
        public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException {
            JMeterVariables variabless = getVariables();
    
            if (values.length != desc.size()) {
                log.warn("输入的参数不是" + desc.size() + "个,请检查参数。");
                return null;
            }
    
            String dbResultVName = ((CompoundVariable)this.values[0]).execute().trim();
            String dbName = ((CompoundVariable)this.values[1]).execute().trim();
            String testTableName = ((CompoundVariable)this.values[2]).execute().trim();
            String mapKey = "Tables_in_" + dbName;
            boolean isExist = false;
            List<Map<String, Object>> tablesList = (ArrayList<Map<String, Object>>) variabless.getObject(dbResultVName);
            log.info("数据库【" + dbName + "】的数据表:" + tablesList.toString());
            log.info("----------------------------");
            for (int i = 0; i < tablesList.size(); i ++) {
                Map<String, Object> tableMap = tablesList.get(i);
                if (tableMap.get(mapKey).equals(testTableName)) {
                    isExist = true;
                    log.info("数据表【" + testTableName + "】存在于数据库【" + dbName + "】");
                }
            }
            log.info("----------------------------");
            if (isExist == false) {
                log.info("在数据库【" + dbName + "】查找不到数据表【" + testTableName + "】");
            }
            return Boolean.toString(isExist);
        }
    
        //设置参数值
        @Override
        public void setParameters(Collection<CompoundVariable> collection) throws InvalidVariableException {
            checkMinParameterCount(collection, 3);
            checkParameterCount(collection, 3);
            this.values = collection.toArray();
        }
    
        //返回函数名字
        @Override
        public String getReferenceKey() {
            return KEY;
        }
    
        //返回参数名字
        @Override
        public List<String> getArgumentDesc() {
            return desc;
        }
    }
    

    在你的函数开发工程里,创建一个名为FindTableInDataBase的类,并将上述代码粘贴到该java 文件,然后编译工程,将 jar 包放到${JMeter_Home}/lib/ext路径上,重启 JMeter 即可。

    3、调用函数

    在判断是否需要需要创建数据表时,在 If Controler 控制器上直接调用该函数,根据返回的结果与预期值比对,即可得出是否需要创建数据表。

    if_Controler2.png

    总结

    以上2种方案是我目前能想到解决方案,也是根据我最近学的知识所总结出来的,可能还有其他更加好的方法,期待与大家一同讨论进步。。

    相关文章

      网友评论

        本文标题:JMeter 判断字符串是否存在该集合(List 或数组)

        本文链接:https://www.haomeiwen.com/subject/yygqgxtx.html