如何在JMeter中按条件提取JSON双值并实现随机化?
问题描述
给定服务器返回的JSON响应:
{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sword of Honour", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "test_title", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Sword of Honour", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "India", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } }, "expensive": 10 }
需要实现:随机提取所有title == 'Sword of Honour'的书籍的author与price组合,每次迭代随机返回类似如下格式的结果:
- 迭代1:
{"author":"Nigel Rees","price":8.95} - 迭代2:
{"author":"Herman Melville","price":8.99} - 迭代3:
{"author":"Herman Melville","price":8.99}
此前尝试使用__V函数book{__V([?(@.title == 'Sword of Honour')]_${__Random(1,${title_matchNr},)},)}仅得到单值,寻求正确实现方法。
解决方案
步骤1:提取符合条件的书籍总数
先用JSON Path表达式提取所有标题为Sword of Honour的书籍,同时获取匹配数量:
- JSON Path表达式:
$..book[?(@.title == 'Sword of Honour')] - 将提取结果的变量名设为
matched_books,此时会自动生成matched_books_matchNr变量,存储符合条件的书籍总数(此处为2)。
步骤2:生成随机索引
用__Random函数生成1到${matched_books_matchNr}之间的随机整数,作为选中书籍的索引:
${__Random(1,${matched_books_matchNr},random_index)}
该函数会将随机数存入random_index变量。
步骤3:提取对应书籍的author和price
分别用JSON Path表达式提取对应索引的author和price:
- 提取author:
$..book[?(@.title == 'Sword of Honour')][${random_index}].author,变量名设为random_author - 提取price:
$..book[?(@.title == 'Sword of Honour')][${random_index}].price,变量名设为random_price
步骤4:组合成目标JSON格式
用__groovy函数将两个变量组合成需要的JSON字符串:
${__groovy('{"author":"' + vars.get("random_author") + '","price":' + vars.get("random_price") + '}',)}
这样每次迭代都会随机生成符合要求的author和price组合。
替代简化方案(一步提取)
也可以直接用Groovy脚本一次性完成筛选、随机选择和格式组合,放在JSR223元件中:
import groovy.json.JsonSlurper def jsonResponse = prev.getResponseDataAsString() def slurper = new JsonSlurper() def data = slurper.parseText(jsonResponse) def matchedBooks = data.store.book.findAll { it.title == 'Sword of Honour' } def randomBook = matchedBooks.get(new Random().nextInt(matchedBooks.size())) def result = '{"author":"' + randomBook.author + '","price":' + randomBook.price + '}' vars.put("random_book_pair", result)
之后直接使用${random_book_pair}变量即可获取目标格式的结果。
内容的提问来源于stack exchange,提问作者Kaushal Kumar
相关产品推荐
相关产品推荐

