美文网首页Testing
JAVA 代码调用Jmeter (动态配置请求参数)

JAVA 代码调用Jmeter (动态配置请求参数)

作者: barry_di | 来源:发表于2018-05-18 21:31 被阅读0次

    一、Jmeter如何进行动态设置请求参数

    • Jmeter使用占位符的方式进行动态替换请求参数内容。
            HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();
            httpSamplerProxy.addArgument("data", "${data}");
    
    • 那么替换占位符的数据是存放在哪里呢?答案就是替换的数据存放在每个线程的Context中。

    当Jmeter创建每个Thread的时候都会创建一个Context,而Thread的Context我们可以通过JMeterContextService的getContext方法获取当前的线程的Context.

    二、实现动态配置请求参数方式

    CSV

    Jmeter在图形化界面提供了CSV的方式进行动态配置请求参数。在Java代码中也可以通过CSV方式来进行实现,但是这种方式存在弊端,因为使用CSV是假设数据全部确定的情况下使用,如果我们所需要的请求参数的数据是不确定况下,我们就不可以使用CSV的方式进行处理。

    Monitor

    我们可以通过JMeterThread.java类发现,每个Sample都会调用SampleMonitor进行监视每个Sample,那么我们可以通过SampleMonitor来进行动态设置请求的参数。

    JMeterThread.java
          if (running) {
                Sampler sampler = pack.getSampler();
                sampler.setThreadContext(threadContext);
                // TODO should this set the thread names for all the subsamples?
                // might be more efficient than fetching the name elsewhere
                sampler.setThreadName(threadName);
                TestBeanHelper.prepare(sampler);
    
                // Perform the actual sample
                currentSampler = sampler;
                if (!sampleMonitors.isEmpty()) {
                    for (SampleMonitor sampleMonitor : sampleMonitors) {
                        sampleMonitor.sampleStarting(sampler);
                    }
                }
                try {
                    result = sampler.sample(null);
                } finally {
                    if (!sampleMonitors.isEmpty()) {
                        for (SampleMonitor sampleMonitor : sampleMonitors) {
                            sampleMonitor.sampleEnded(sampler);
                        }
                    }
                }
                currentSampler = null;
            }
    

    三、时序图

    image.png

    三、代码实现

    1. TestPlanLauncher.java

    public class TestPlanLauncher {
    
        public static void main(String[] args) {
            // jemter 引擎
            StandardJMeterEngine standardJMeterEngine = new StandardJMeterEngine();
            // 设置不适用gui的方式调用jmeter
            System.setProperty(JMeter.JMETER_NON_GUI, "true");
            // 设置jmeter.properties文件,我们将jmeter文件存放在resources中,通过classload
            String path = TestPlanLauncher.class.getClassLoader().getResource("jmeter.properties").getPath();
            File jmeterPropertiesFile = new File(path);
            if (jmeterPropertiesFile.exists()) {
                JMeterUtils.loadJMeterProperties(jmeterPropertiesFile.getPath());
                HashTree testPlanTree = new HashTree();
                // 创建测试计划
                TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
                String variableNames = "data";
                // 创建http请求收集器
                HTTPSamplerProxy examplecomSampler = createHTTPSamplerProxy(variableNames);
                // 创建循环控制器
                LoopController loopController = createLoopController();
                // 创建线程组
                ThreadGroup threadGroup = createThreadGroup();
                // 线程组设置循环控制
                threadGroup.setSamplerController(loopController);
                // 将测试计划添加到测试配置树种
                HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);
                // 将http请求采样器添加到线程组下
                threadGroupHashTree.add(examplecomSampler);
                //增加监视器
                threadGroupHashTree.add(createHttpSampleMonitor(variableNames));
                //增加结果收集
                Summariser summer = null;
                String summariserName = JMeterUtils.getPropDefault("summariser.name", "summary");
                if (summariserName.length() > 0) {
                    summer = new Summariser(summariserName);
                }
                ResultCollector logger = new ResultCollector(summer);
                testPlanTree.add(testPlanTree.getArray(), logger);
                // 配置jmeter
                standardJMeterEngine.configure(testPlanTree);
                // 运行
                standardJMeterEngine.run();
            }
        }
    
        /**
         * 创建线程组
         * 
         * @return
         */
        public static ThreadGroup createThreadGroup() {
            ThreadGroup threadGroup = new ThreadGroup();
            threadGroup.setName("Example Thread Group");
            threadGroup.setNumThreads(1);
            threadGroup.setRampUp(0);
            threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
            threadGroup.setScheduler(true);
            threadGroup.setDuration(60);
            threadGroup.setDelay(0);
            return threadGroup;
        }
    
        /**
         * 创建循环控制器
         * 
         * @return
         */
        public static LoopController createLoopController() {
            // Loop Controller
            LoopController loopController = new LoopController();
            loopController.setLoops(-1);
            loopController.setContinueForever(true);
            loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
            loopController.initialize();
            return loopController;
        }
    
        /**
         * 增加监视器
         * @param variableNames
         * @return
         */
        public static HttpSampleMonitor createHttpSampleMonitor(String variableNames){
            HttpSampleMonitor httpSampleMonitor = new HttpSampleMonitor();
            if (StringUtils.isNoneBlank(variableNames)) {
                httpSampleMonitor.setProperty("variableNames",variableNames);
            }
            return httpSampleMonitor;
        }
        /**
         * 创建http采样器
         * 
         * @return
         */
        public static HTTPSamplerProxy createHTTPSamplerProxy(String variableNames) {
            HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();
            httpSamplerProxy.addArgument(variableNames, "${"+variableNames+"}");
            httpSamplerProxy.setDomain("www.baidu.com");
            httpSamplerProxy.setPort(80);
            httpSamplerProxy.setPath("/");
            httpSamplerProxy.setMethod("GET");
            httpSamplerProxy.setConnectTimeout("5000");
            httpSamplerProxy.setUseKeepAlive(true);
            httpSamplerProxy.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
            return httpSamplerProxy;
        }
    }
    
    

    2.HttpSampleMonitor

    public class HttpSampleMonitor extends ConfigTestElement implements SampleMonitor {
        private static final Logger log = LoggerFactory.getLogger(HttpSampleMonitor.class);
    
        private static final long serialVersionUID = 23221L;
    
        // 请求变量名以逗号分隔
        private String variableNames;
        // 分隔后的变量名
        private String[] vars;
        @Override
        public void sampleStarting(Sampler sampler) {
            final JMeterContext context = getThreadContext();
            JMeterVariables threadVars = context.getVariables();
            if (StringUtils.isNoneEmpty(getVariableNames())) {
                vars = JOrphanUtils.split(getVariableNames(), ",");
                trimVarNames(vars);
                for (int i = 0; i < vars.length; i++) {
                    threadVars.put(vars[i], i + "");
                }
            }
        }
    
        @Override
        public void sampleEnded(Sampler sampler) {
    
        }
    
        /**
         * trim content of array varNames
         * 
         * @param varsNames
         */
        private void trimVarNames(String[] varsNames) {
            for (int i = 0; i < varsNames.length; i++) {
                varsNames[i] = varsNames[i].trim();
            }
        }
        public String getVariableNames() {
            this.variableNames = this.getPropertyAsString("variableNames");
            return variableNames;
        }
    
    }
    

    3.特别说明

    • 在HTTPSamplerProxy中的addArgument方法设置的占位符需要使用${}的形式。并且要与HttpSampleMonitor中threadVars对象put的name保持一致。
    • HttpSampleMonitor:我们的HttpSampleMonitor是为每一个线程增加一个HttpSampleMonitor,所以Jmeter需要对HttpSampleMonitor进行对象的clone和对clone的对象设置Property. 我们可以通过继承ConfigTestElement来获取对象拷贝和Property设置的能力。

    Reference:
    https://jmeter.apache.org/api/index.html

    相关文章

      网友评论

        本文标题:JAVA 代码调用Jmeter (动态配置请求参数)

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