JMeter MongoDB插入脚本未正确读取CSV迭代值问题咨询
问题背景
现有配置
- CSV数据集配置:对应配置可参考配套配置截图
- 线程组配置:线程数设置为1,循环次数设置为3
- JMeter MongoDB插入脚本原始代码:
import com.mongodb.* import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClient; import com.mongodb.MongoClientSettings; import com.mongodb.ServerAddress; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import java.util.Arrays; try { MongoCollection<Document> collection = vars.getObject("collection"); Document document = new Document("_id", "${_id}") .append("has_mortgages",false) .append("data", new Document ("etag":"${_etag}") .append("links", new Document ("charges","/company/${_id}/charges")) ); collection.insertOne(document); } catch (Exception e) { SampleResult.setSuccessful(false); SampleResult.setResponseCode("500"); SampleResult.setResponseMessage("Exception: " + e); }
运行异常
第一次迭代可以正常读取_id取值PT000001并完成记录插入;第二次迭代虽然能从CSV中正确识别到当前迭代的_id值PT000002,但执行collection.insertOne(document)语句时,实际插入的记录_id值仍然是PT000001。
问题根因
- 核心问题是JSR223脚本使用Groovy语言时,脚本编译结果会被缓存,直接在脚本中写
${变量名}形式的JMeter函数/变量,只会在脚本第一次编译执行时被替换为当前值,后续迭代运行时会直接使用缓存的编译后脚本,不会重新解析替换变量值。你脚本里的"${_id}"、"${_etag}"在第一次迭代时就被硬编码替换为PT000001和对应的etag值,后续循环不会再读取CSV的新行取值。 - 脚本中
new Document ("etag":"${_etag}")属于语法错误,MongoDB Java驱动的Document构造方法接收键、值两个入参,应该用逗号分隔,冒号是JSON格式的写法,在Java代码中无法正常解析。
修复方案
不要在Groovy脚本中直接使用${}形式引用JMeter变量,改用JMeter内置的vars.get("变量名")方法实时读取当前迭代的变量值,同时修正Document构造的语法错误,修改后的可运行脚本如下:
import com.mongodb.client.MongoCollection; import org.bson.Document; try { MongoCollection<Document> collection = vars.getObject("collection"); // 实时读取当前迭代的CSV参数值 String currentId = vars.get("_id"); String currentEtag = vars.get("_etag"); Document document = new Document("_id", currentId) .append("has_mortgages", false) .append("data", new Document("etag", currentEtag) .append("links", new Document("charges", "/company/" + currentId + "/charges")) ); collection.insertOne(document); } catch (Exception e) { SampleResult.setSuccessful(false); SampleResult.setResponseCode("500"); SampleResult.setResponseMessage("Exception: " + e); }
额外配置校验项:
- 确认CSV数据集配置中「Recycle on EOF」设置为
False、「Stop thread on EOF」设置为True,避免CSV数据读取完毕后重复返回第一行取值 - 确认CSV文件的实际编码和CSV数据集配置中选择的编码一致,避免乱码导致取值异常
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

