2

I am very new to Postman. I want to compare JSON body object response.

json_response = JSON.parse(responseBody);
x=json_response.counter
pm.expect(x).to.equal("400");

It gives me 400 value of that corresponding 'counter' (or '400' Value of Key 'counter')

But I would like to compare 'counter' to 'counter' itself. (cases like, Counter, CounTer, etc.)

{

    "counter": 400,
    "validInMinutes": 660,
    "currentCounter": 322,

}

Basically, I want to test that received all JSON Keys are equal to what I am looking for! Is there an easy way to do it?

VLAZ
  • 26,331
  • 9
  • 49
  • 67
kishorK
  • 453
  • 2
  • 7
  • 16
  • compare them with ```.toLowerCase()``` because right now 'Counter' doesn't exist as the key you have is 'counter'. – Jabberwocky May 08 '19 at 12:55
  • JSON is the string used to transmit a Javascript Object. JSON stands for Javascript Object Notation. You are not comparing keys in a "JSON body" you are comparing keys in a javascript object. – Marie May 08 '19 at 12:58
  • @Jabberwocky that is bad advice because properties are case sensitive. – Marie May 08 '19 at 12:58
  • @kishor What are the keys that you are looking for? – Krishna Prashatt May 08 '19 at 13:01
  • 1
    It looks like you are expecting a string to equal a number ("400" is not the same as 400) – transporter_room_3 May 08 '19 at 13:03
  • @Marie he was talking about counter specifically. And also if you use to lowercase on both sides of the comparison, it would still be fine. – Jabberwocky May 08 '19 at 13:04
  • "*But I would like to compare 'counter' to 'counter' itself. (cases like, Counter, CounTer, etc.)*" what do you mean? Check if the key `counter` is spelled `counter` and not `counTer`? Or what? – VLAZ May 08 '19 at 13:05
  • @KrishnaPrashatt I want to compare all those 3 keys from my JSON output ( counter, validInMinutes, currentCounter) – kishorK May 08 '19 at 13:06
  • @kishor compare the keys **with what**? or compare them one with other? – Krishna Prashatt May 08 '19 at 13:07
  • Compare the *keys* or compare *the values*? And what is the expected result from comparing them - what do you want that to give you? – VLAZ May 08 '19 at 13:07
  • @KrishnaPrashatt sorry for my Bad explanation but I will try to make to simple. I want to compare KEYS with KEYS only. I am just confused that should i use loop and compare my JSON output of only keys to some array. Sould I store 3 KEYS in any array and then compare it with JSON Key list. ? – kishorK May 08 '19 at 13:18
  • @kishor So you are telling, you are already having a list of keys and you need to compare them with the key list you are receiving from response? – Krishna Prashatt May 08 '19 at 13:21
  • @VLAZ Keys, not the Values – kishorK May 08 '19 at 13:22
  • @KrishnaPrashatt Yes, my JSON output looks same as mentioned in Question. – kishorK May 08 '19 at 13:26
  • @kishor and what is the expected result of that? Do you want to check if each of a list of predefined key exists in the result? Do you want to ensure that the result *only* has the predefined list of keys and fail if it misses or has any extra ones? Do you want to instead inverse that and check if the result contains keys that are in a predefined list (as opposed to a predefined list in the result)? What should happen when you compare the keys to something else? – VLAZ May 08 '19 at 13:27
  • @KrishnaPrashatt For Example, json_response = JSON.parse(responseBody); x=json_response.counter pm.expect(x).to.equal("counter"); But this code gives the value of 'counter' Key which is 400 not the Key itself. so Is there a way to compare Key with Key ? – kishorK May 08 '19 at 13:28
  • you can check `Object.keys(json_response)` this will give all keys of the response or you can use `for(let key in json_response)` and check for `indexOf` comparing the keys with your array list – Krishna Prashatt May 08 '19 at 13:31
  • @VLAZ Thank you for writing a lot for my question. Yes, I would like to PASS it when the JSON Key is equal to my expectations. for example, pm.expect(x).to.equal("counter"). But I it doesnt compare the Keys, It will look for Values. – kishorK May 08 '19 at 13:34
  • @KrishnaPrashatt Thank you but once i have list of Key then how to test with my array. Is it possible without loop ? something like this: pm.expect(Object.keys(jsonData)).to.eql("counter"); without loop I still want to compare all 3 parameters. – kishorK May 08 '19 at 13:40
  • @kishor well, you cant avoid loops because there is no ordering in an object.i.e., you cannot expect the keys to follow a particular order. – Krishna Prashatt May 08 '19 at 13:43
  • I removed my answer temporarily. I knew Postman used Chai for its tests but apparently...it doesn't any more. And the documentation for their test syntax is a bit hard to find. I'll update my answer and re-post the answer. – VLAZ May 08 '19 at 14:01
  • Re-posted the answer. Postman's documentation is really frustrating. I found few places that said they *used* to use Chai and don't any more and yet the official documentation says that Postman does actually use Chai. I am fairly sure that's the case but they seem to just be exposing it through that `pm` interface. But it's not very well explained. – VLAZ May 08 '19 at 14:26

2 Answers2

2

Postman's pm.expect uses the Chai library for assertions (this links to pm.cookies but the entry for pm.expect is under that heading, for some reason). A using the Chai API you can verify the response only has the keys you expect by saying expect(someObject).to.have.keys(expectedKeys) and define what the keys should be:

//for convenience - in Postman, these would be readily available. 
var pm = { 
  expect: chai.expect, 
  response: {
    json: function() {
      // the response you would get
      return { "counter": 400, "validInMinutes": 660, "currentCounter": 322 };
    }
  }
};

/* --- test script begins --- */

var expectedKeys = ["counter", "validInMinutes", "currentCounter"];

pm.expect(pm.response.json()).to.have.keys(expectedKeys); // OK
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>

And here are some examples of how this can expectation can fail:

var pm = { 
  expect: chai.expect, 
  response: {
    json: function() {
      // "Counter" starts with capital C
      return { "Counter": 400, "validInMinutes": 660, "currentCounter": 322 };
    }
  }
};

/* --- test script begins --- */

var expectedKeys = ["counter", "validInMinutes", "currentCounter"];

pm.expect(pm.response.json()).to.have.keys(expectedKeys); // fails
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>

var pm = { 
  expect: chai.expect, 
  response: {
    json: function() {
      // "counter" is missing
      return { "validInMinutes": 660, "currentCounter": 322 };
    }
  }
};

/* --- test script begins --- */

var expectedKeys = ["counter", "validInMinutes", "currentCounter"];

pm.expect(pm.response.json()).to.have.keys(expectedKeys); // fails
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>

var pm = { 
  expect: chai.expect, 
  response: {
    json: function() {
      //same object you have...
      return { "counter": 400, "validInMinutes": 660, "currentCounter": 322 };
    }
  }
};

/* --- test script begins --- */

//...but there is an extra expected key
var expectedKeys = ["counter", "validInMinutes", "currentCounter", "otherKey"];

pm.expect(pm.response.json()).to.have.keys(expectedKeys); // fails
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.min.js"></script>
VLAZ
  • 26,331
  • 9
  • 49
  • 67
1

You have a specific schema in your mind, that you want to check. (e.g. Mandatory fields, Types, etc.) An other possible way is to validate against a pre-defined JSON-schema:

//Schema definition (can be available as a global var)
var schema = {
    "type": "object",
    "properties": {
        "counter": {
            "type": "number"
        },
        "validInMinutes": {
            "type": "number"
        },
        "currentCounter": {
            "type": "number"
        }
    },
    "required": ["counter", "validInMinutes", "currentCounter"]
};

//Test
pm.test('Schema is valid', function() {
    var jsonData = pm.response.json();
    pm.expect(tv4.validate(jsonData, schema)).to.be.true;
});

The Line "required": ["counter", "validInMinutes", "currentCounter"] is exactly your definition of what kind of properties must be there. But you can also define more strct rules, as "must be of type Numer", or must have exactly 3 digits, and so on.

DieGraueEminenz
  • 830
  • 2
  • 8
  • 18