如何在 JMeter 中断言每次都以随机顺序产生结果的 JSON 响应?

How to assert a JSON response which have results in random order every time in JMeter?

我正在使用 JSON 断言来断言 JSON 路径是否存在。假设我有一个 JSON 的 'rooms' 数组响应 'contains' 一个柜子数组,就像下面的例子

"rooms":
[
    {
        "cabinets":
        [
            {
                "id":"HFXXXX",
                "locationid":null,
                "name":"HFXXXX",
                "type":"Hosp"
            },
            {
                "id":"HFYYYY",
                "locationid":null,
                "name":"HFYYYY",
                "type":"Hosp"
            },
            {
                "id":"HFZZZZ",
                "locationid":null,
                "name":"HFZZZZ",
                "type":"Hosp"
            }
        ],
        "hasMap":false,
        "id":"2",
        "map":
        {
            "h":null,
            "w":null,
            "x":null,
            "y":null
        },
        "name":"Fantastic Room#3"
    }
],
[
    {   "cabinets":
        [
            {
                "id":"HFBBBB",
                "locationid":null,
                "name":"HFBBBB",
                "type":"Hosp"
            }
        ],
        "hasMap":false,
        "id":"3",
        "map":
        {
            "h":null,
            "w":null,
            "x":null,
            "y":null
        },
        "name":"BallRoom #4"
    }
]

我想确保所有机柜的'id'都是正确的,因此我将JSON路径定义为rooms[*].cabinets[*].id并期望值为["HFXXXX","HFYYYY","HFZZZZ","HFBBBB"]

除了有时以不同的顺序 ["HFBBBB", "HFXXX","HFYYYY","HFZZZZ"] 而不是 ["HFXXXX","HFYYYY","HFZZZZ","HFBBBB"] 返回值外,这非常有效,因此断言将失败。问题在于返回数组的顺序,而不是值本身。

有没有办法在断言之前对响应的顺序进行排序并继续使用 JSON 断言?或者这样做的唯一方法是提取我想要断言的值并在 JSR223 断言(groovy 或 javascript)中使用它? 如果是这样的话,你能告诉我一个例子,说明我如何在 JSR223 插件中做到这一点。

我建议使用专用库,例如​​ JSONAssert,这样您就不必重新发明轮子,并且可以在一行代码中比较 2 JSON 个对象

  1. 下载jsonassert-x.x.x.jar and put it somewhere to JMeter Classpath
  2. 下载合适版本的 JSON in Java 库并将其也放入 JMeter 类路径。如果您不确定 "JMeter Classpath" 是什么,只需将 .jars 放到 JMeter 安装的 "lib" 文件夹中
  3. 重新启动 JMeter 以便它能够加载新库
  4. JSR223 Assertion 添加为上述 returns JSON
  5. 请求的子项
  6. 将以下代码放入"Script"区域:

    def expected = vars.get('expected')
    def actual = prev.getResponseDataAsString()
    
    org.skyscreamer.jsonassert.JSONAssert.assertEquals(expected, actual, false)
    

    它将父采样器的响应与 ${expected} JMeter 变量的内容进行比较,元素的顺序、换行的存在、格式无关紧要,它只比较键和值

    如果不匹配,您将收到错误消息,指出断言结果和完整的调试输出将在 STDOUT(您启动 JMeter 的控制台)