You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:02:30