JMeter中Groovy按变量定位CSV行并遍历生成请求XML的实现方案
JMeter动态生成XML请求体问题修复方案
故障原因
- 语法错误:
reoderedCsv.take numberOfNodes eachWithIndex写法不符合Groovy语法规则,导致解析器错误识别遍历对象,拿到的data不是预期的键值对Map,而是字符串迭代对象,最终生成XML时把每个字符单独包裹在doc标签中 - 取数逻辑缺陷:直接调用
take(numberOfNodes)最多只能取到和CSV行数相等的节点,无法满足节点数超过CSV行数时循环取数补全的需求 - 缺少日期格式转换:未将CSV中
yyyy-MM-dd格式的日期转换为示例要求的MM/dd/yyyy格式 - 固定起始值:目前起始查询的姓名是硬编码,未对接CSV Data Set Config的动态变量
修正后完整代码
def pReqID = 'ID0000' def numberOfNodes = 10 // 从CSV Data Set Config获取动态起始姓名变量 String startFrom = vars.get('iName') int pos = -1 // 日期转换规则 def dateFormatter = new java.text.SimpleDateFormat("yyyy-MM-dd") def targetFormatter = new java.text.SimpleDateFormat("MM/dd/yyyy") // 读取CSV文件,跳过表头行 def csv = new File("TestData/validTravellerDocuments.csv").readLines().drop(1).withIndex().collect { line, idx -> def (docType, docId, name, dateStr) = line.trim().split(',') // 定位起始行位置 if (pos == -1 && startFrom == name) { pos = idx } // 转换日期格式 def date = dateFormatter.parse(dateStr) return [docType: docType, docId: docId, name: name, date: targetFormatter.format(date)] } // 重排CSV顺序,从指定起始行开始 def reorderedCsv = pos > -1 ? csv.subList(pos, csv.size()) + csv.subList(0, pos) : csv def writer = new StringWriter() def xml = new groovy.xml.MarkupBuilder(writer) xml.nodes() { // 循环取数补足所需节点数,用模运算实现循环读取 (0..<numberOfNodes).each { idx -> def data = reorderedCsv[idx % reorderedCsv.size()] object(a: 'false', b: 'false', pReqID: "${pReqID}${idx + 1}") { al(ad: '2021-09-20', alc: 'bla', bla: '2021-09-20T11:00:00.000Z', sn: 'AB8912') // 明确传入Map作为doc标签的属性 doc(data) } } } def nodesAsText = writer.toString() log.info(nodesAsText) // 存入JMeter变量供采样器使用 vars.put('passengers3XmlObj', nodesAsText)
效果说明
- 当CSV只有示例3行数据,
iName变量值为Dominique时,生成的XML结构和给出的预期完全一致 - 当
numberOfNodes大于CSV行数时,会自动循环重排后的CSV数据补足节点,不会出现取数报错 - 支持对接CSV Data Set Config的动态变量,每次迭代传入不同的
iName就会从对应行开始生成请求体
内容的提问来源于stack exchange,提问作者JustNatural
相关产品推荐
相关产品推荐

