【问题标题】:How to write a postman test to compare the response json against another json?如何编写邮递员测试以将响应 json 与另一个 json 进行比较?
【发布时间】:2018-01-18 20:07:08
【问题描述】:

在运行 Rest API 的 postMan 测试后,我得到以下 json 响应:

    {
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

现在我想将上面的 json 与预定义的 json 进行比较。说,和上面一样。

如何通过 Postman 测试比较两个 json?

【问题讨论】:

  • Praveesh,您应该接受以下答案之一,如果它们能解决您的问题。
  • 这是我很久以前做过的一个老项目。中间丢了。有时间我会试试的。

标签: javascript json postman


【解决方案1】:

我有一个类似的问题要解决,只是我的 JSON 还包含一个对象数组。我使用了以下可以修改的技术来处理您问题中的简单字符串数组。我创建了一个名为“assert”的全局函数数组,其中包含“areEqual”和“areArraysOfObjectsEqual”等辅助函数并将它们保存在我的测试顶部文件夹级别的“测试”选项卡。

assert = {
    areEqual: (actual, expected, objectName) => {
        pm.test(`Actual ${objectName} '` + actual + `' matches Expected ${objectName} '` + expected + `'`, () => {
            pm.expect(_.isEqual(actual, expected)).to.be.true;
        });
    },
    areArraysOfObjectsEqual: (actual, expected, objectName) => {
        if (!_.isEqual(actual, expected)) {

            // Arrays are not equal so report what the differences are
            for (var indexItem = 0; indexItem < expected.length; indexItem++) {
                assert.compareArrayObject(actual[indexItem], expected[indexItem], objectName);
            }
        }
        else
        {
            // This fake test will always pass and is just here for displaying output to highlight that the array has been verified as part of the test run
            pm.test(`actual '${objectName}' array matches expected '${objectName}' array`);
        }
    },
    compareArrayObject: (actualObject, expectedObject, objectName) => {
        for (var key in expectedObject) {
            if (expectedObject.hasOwnProperty(key)) {
                assert.areEqual(expectedObject[key], actualObject[key], objectName + " - " + key);
            }
        }
    }
};

您用于测试的“预请求脚本”将设置您的预期对象

 const expectedResponse =
    {
        "id": "3726b0d7-b449-4088-8dd0-74ece139f2bf",
        "array": [
            {
                "item": "ABC",
                "value": 1
            },
            {
                "item": "XYZ",
                "value": 2
            }
        ]
    };

    pm.globals.set("expectedResponse", expectedResponse); 

您的测试将单独或在数组级别测试每个项目,如下所示:

const actualResponse = JSON.parse(responseBody);
const expectedResponse = pm.globals.get("expectedResponse");

assert.areEqual(
    actualResponse.id,
    expectedResponse.id,
    "id");

assert.areArraysOfObjectsEqual(
    actualResponse.myArray,
    expectedResponse.myArray,
    "myArrayName");

这种技术将提供很好的“属性名称实际值与预期值匹配”输出,并适用于作为被比较 JSON 一部分的对象数组。

更新: 要测试您的字符串数组“GlossSeeAlso”,只需在您的任何测试中调用提供的全局帮助器方法,如下所示:

assert.compareArrayObject(
    actualResponse.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso,       
    expectedResponse.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso,
    "glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso");

JSON 键值对中的原始类型可以这样测试:

assert.areEqual(
    actualResponse.glossary.title,
    expectedResponse.glossary.title,
    "glossary.title");

【讨论】:

    【解决方案2】:

    您可以将此代码粘贴到您的集合或单个请求测试选项卡中。

    这段代码的作用是将请求保存到一个全局变量中,并带有该请求的键。您可以更改您的环境并点击相同的请求,如果响应不同,则测试将失败。

    const responseKey = [pm.info.requestName, 'response'].join('/');
    let res = '';
    try {
        res = JSON.stringify(pm.response.json());
    } catch(e) {
        res = pm.response.text();
    }
    
    if (!pm.globals.has(responseKey)) {
        pm.globals.set(responseKey, res);
    } else {    
        pm.test(responseKey, function () {
            const response = pm.globals.get(responseKey);
            pm.globals.unset(responseKey);
            try {
                const data = pm.response.json();
                pm.expect(JSON.stringify(data)).to.eql(response);
            } catch(e) {
                const data = pm.response.text();
                pm.expect(data).to.eql(response);
            }
        });
    }
    

    希望对您有所帮助。

    【讨论】:

    • 这真的很聪明@Anthony。我希望我们能在 SO 上看到更多您的回答。
    【解决方案3】:

    过了一会儿我就知道了。将测试添加到您的请求中并使用 Runner 运行集合中的所有请求。

    邮递员信息:Mac 版本 7.10.0。

    测试脚本:

    pm.test("Your test name", function () {
        var jsonData = pm.response.json();
        pm.expect(jsonData).to.eql({
            "key1": "value1",
            "key2": 100
        });
    });
    

    【讨论】:

      【解决方案4】:

      您可以在 Postman 的 Tests tab 中编写 javascript 代码。只需编写简单的代码即可在 Tests 中比较和检查结果。

      var serverData = JSON.parse(responseBody);
      var JSONtoCompare = {}; //set your predefined JSON here.
      tests["Body is correct"] = serverData === JSONtoCompare;
      

      【讨论】:

      • 嗨@yogen darji,我试过这个,但测试失败并显示“身体不正确”消息。
      • @PraveeshP 您收到 400 Bad request 还是 200 OK 作为响应?
      • @PraveeshP 如果找到有用的答案,请标记为答案:)
      • 它不工作。我的意思是说我的第一个测试只是检查 200 响应代码并且它有效。但第二个是比较失败的json。
      • 如果您的 JSONtoCompare 是一个巨大的对象,跨越数百行,这不是一个可扩展的解决方案。
      【解决方案5】:

      看起来与POSTMAN: Comparing object Environment variable with response's object 提出的相同问题还列出了一个可行的解决方案,即使用JSON.stringify()objects 转换为strings,然后比较字符串。

      【讨论】:

      • 在建议的解决方案下阅读评论是值得的:在比较两个字符串化的 JSON 时,对象的顺序很重要,这可能导致错误的不匹配。 Postman 支持一个全面的断言框架,它允许您在对象级别上比较 JSON,而不是作为字符串表示。我宁愿使用使用对象表示的解决方案之一,也不愿选择JSON.stringify() 路线。
      【解决方案6】:

      从旧 API 迁移到新 API 时遇到此问题,并希望在不同场景下断言新 API 与旧 API 完全相同

      对于上下文,这会将原始 get 请求的参数克隆到旧端点并验证两者是否匹配

      LEGACY_API_URL 应在环境中定义,并且请求将转到新的 API

      const { Url } = require('postman-collection');
      
      // Setup the URL for the Legacy API
      const legacyRequestUrl = new Url({ host: pm.variables.replaceIn("http://{{LEGACY_API_HOST}}/blah")});
      
      // Add All Parameters From the Source Query
      legacyRequestUrl.addQueryParams(pm.request.url.query.all());
      
      // Log out the URL For Debugging Purposes
      console.log("URL", legacyRequestUrl.toString());
      
      pm.sendRequest(legacyRequestUrl.toString(), function (err, response) {
          pm.test('New API Response Matches Legacy API Response', function () {
      
              // Log Out Responses for Debugging Purposes
              console.log("New API Response", pm.response.json())
              console.log("Legacy API Response", response.json())
      
              // Assert Both Responses are Equal
              pm.expect(_.isEqual(pm.response.json(), response.json())).to.be.true
          });
      });

      链接到示例集合


      https://www.getpostman.com/collections/4ff9953237c0ab1bce99

      【讨论】:

        【解决方案7】:

        在“测试”部分下编写 JavaScript 代码。请参阅下面的链接了解更多信息。

        Click Here

        【讨论】:

        • 首先,不要只是告诉人们盲目地点击链接。如果链接断开,请在您的答案中包含有用的信息。其次,如果您想在答案中宣传您自己的网站,您至少可以公开这一点,并将其指向回答问题的确切位置。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-18
        • 1970-01-01
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 2018-06-27
        相关资源
        最近更新 更多