如何在Java代码中读取JMeter JSR223断言处理的timestamp与diff值
如何在Java代码中读取JMeter JSR223断言的处理结果?
看起来你已经在JMeter脚本里通过JSR223断言算出了timestamp和diff,但在Java主程序里拿不到这些值对吧?之前用SamplerListener没生效,大概率是因为线程局部变量的隔离或者监听器时机不对。下面给你两个可行的方案,优先推荐第一种,简单直接:
方案一:利用JMeter全局属性+TestListener获取结果
步骤1:修改JSR223断言,把结果存入全局Properties
你的原代码里用vars.putObject存的是线程局部变量,Java主程序没法直接拿到。换成全局的props(JMeter的Properties对象),整个JMeter实例都能访问:
import groovy.json.JsonBuilder String totalIDs = vars.get("assetIdCount_matchNr"); Integer result = Integer.valueOf(totalIDs); Date currentDate = new Date(); if (result > 10){ String searchTimestamp = currentDate.getTime().toString(); vars.put("SEARCH_SUCCESS_TIMESTAMP", searchTimestamp); // 关键修改:把结果存入全局props,而不是线程局部的vars props.put("RESULT_TIMESTAMP", searchTimestamp); Long creationTimestamp = Long.valueOf(props.get("ASSET_CREATION_TIMESTAMP").toString()); Long diff = Long.valueOf(searchTimestamp) - creationTimestamp; props.put("RESULT_DIFF", diff.toString()); vars.putObject("Diff", diff); log.info("计算得到的diff值:" + diff); // 保留原有的文件写入逻辑(可选) def json = new JsonBuilder() def root = json timestamp: searchTimestamp, diff: diff def file = new File(vars.get("file_location").toString()) file.write('\n'+json.toString()); sleep 10 AssertionResult.setFailure(true); }
步骤2:在Java代码中添加自定义TestListener
TestListener会在测试运行结束时触发,此时所有断言都已经执行完毕,我们可以从JMeter的全局属性中提取结果:
import org.apache.jmeter.engine.StandardJMeterEngine; import org.apache.jmeter.util.JMeterUtils; import org.apache.jmeter.testelement.TestListener; // 自定义监听器,用于捕获测试结束事件 class ResultCaptureListener implements TestListener { private String timestamp; private String diff; @Override public void testStarted() {} @Override public void testStarted(String host) {} @Override public void testEnded() { // 从全局props中提取之前存入的结果 this.timestamp = JMeterUtils.getJMeterProperties().getProperty("RESULT_TIMESTAMP"); this.diff = JMeterUtils.getJMeterProperties().getProperty("RESULT_DIFF"); } @Override public void testEnded(String host) { testEnded(); // 复用testEnded逻辑 } // 提供获取结果的方法 public String getTimestamp() { return timestamp; } public String getDiff() { return diff; } } // 你的原有Java代码修改部分 public void runJMeterTest() { StandardJMeterEngine jmeterSecondary = configJmeter(jmxFileName, argumentObject, jmeter, jMeterAssetECListnerService); // 创建自定义监听器并注册到JMeter引擎 ResultCaptureListener resultListener = new ResultCaptureListener(); jmeterSecondary.registerTestListener(resultListener); // 运行JMeter jmeterSecondary.run(); // 这里就可以获取结果了! String timestamp = resultListener.getTimestamp(); String diff = resultListener.getDiff(); System.out.println("从JMeter拿到的timestamp:" + timestamp); System.out.println("从JMeter拿到的diff:" + diff); jmeterSecondary.reset(); jmeterSecondary.exit(); }
方案二:通过自定义ResultCollector捕获采样器结果(更复杂但灵活)
如果需要更细粒度的控制,比如监听每个采样器的断言结果,可以自定义ResultCollector:
- 创建一个继承自
ResultCollector的类,重写sampleOccurred方法,在里面解析采样器的响应或变量。 - 把这个Collector添加到JMeter的测试计划中。
不过这个方案需要你熟悉JMeter的采样器结果结构,不如方案一直接,所以优先推荐方案一。
为什么之前的SamplerListener没用?
SamplerListener是监听单个采样器的执行结果,而你的断言是在采样器执行后运行的。如果监听器触发时断言还没执行完,或者你没有把监听器正确关联到目标采样器上,就拿不到结果。而用全局props+TestListener,是在整个测试结束后统一获取,时机更可靠。
内容的提问来源于stack exchange,提问作者Knight95
相关产品推荐
相关产品推荐

