Verify in Response place name for Each country and Postal Code

I am new to Postman and learning how to traverse through CSV file. I am trying to find out Place Name against the combination of Country Name and Postal Code. For instance, if the Country is US and the Postal Code is 90210, it should return Beverly Hills and the Test should pass. If this US and Postal Code is 12345, this should return Schenectady. This should iterate for rest of the Entries.

My CSV file looks like this:
Country,Postal Code,Place Name
us,90210,Beverly Hills
us,12345,Schenectady
ca,B2R,Waverley

Could you please help? Many thanks in advance!

If you are using a CSV file in the Collection Runner, then this will run your collection once for each line in your CSV file.

If you want to check all of the data against a single response, then you are better off using a JSON data file instead where you can create a top level object and then have your tests as an array underneath that.

This way, you can iterate over the array against a single response.

Can you please confirm if this is a single request, or will actually be multiple requests. One for each line in your CSV?

Postman uses JavaScript under the hood. So you can search your response for the country and postcode using the JavaScript “Find” function, and then assert on the place name.

I can show you how to do this, but you need to provide an example response with at least two objects in it.

@michaelderekjones many thanks for the Response. I am using NEWMAN CLI. This has to be one request each iteration and each line should be checked against Country and Post Code in order to find a respective Place Name in their respective Iterations.
I have in the Meanwhile tried to read the CSV Data into JSON format within the Script. I am putting this under the Comments. By the Way, CSV is not a must. If this is easier to be done with JSON, that should work too :slight_smile:
One question, is it possible to read the whole CSV and make a full JSON out of it for all the Rows? If yes, could you please tell me how? Many thanks in advance :slight_smile: !

{
“post code”: “12345”,
“country”: “United States”,
“country abbreviation”: “US”,
“places”: [
{
“place name”: “Schenectady”,
“longitude”: “-74.058”,
“state”: “New York”,
“state abbreviation”: “NY”,
“latitude”: “42.8333”
},
{
“post code”: “90210”,
“country”: “United States”,
“country abbreviation”: “US”,
“places”: [
{
“place name”: “Beverly Hills”,
“longitude”: “-118.4065”,
“state”: “California”,
“state abbreviation”: “CA”,
“latitude”: “34.0901”
}
]
},
{
“post code”: “B2R”,
“country”: “Canada”,
“country abbreviation”: “CA”,
“places”: [
{
“place name”: “Waverley”,
“longitude”: “-63.5144”,
“state”: “Nova Scotia”,
“state abbreviation”: “NS”,
“latitude”: “44.7431”
}
]
}
]
}

Please use the pre-formatted text option in the editor when pasting code or JSON, so everything doesn’t end up aligned to the left.

{
    "post code": "12345",
    "country": "United States",
    "country abbreviation": "US",
    "places": [
        {
            "place name": "Schenectady",
            "longitude": "-74.058",
            "state": "New York",
            "state abbreviation": "NY",
            "latitude": "42.8333"
        },
        {
            "post code": "90210",
            "country": "United States",
            "country abbreviation": "US",
            "places": [
                {
                    "place name": "Beverly Hills",
                    "longitude": "-118.4065",
                    "state": "California",
                    "state abbreviation": "CA",
                    "latitude": "34.0901"
                }
            ]
        },
        {
            "post code": "B2R",
            "country": "Canada",
            "country abbreviation": "CA",
            "places": [
                {
                    "place name": "Waverley",
                    "longitude": "-63.5144",
                    "state": "Nova Scotia",
                    "state abbreviation": "NS",
                    "latitude": "44.7431"
                }
            ]
        }
    ]
}

Can you please check\correct the JSON as it doesn’t look right.

Please correct the JSON, and I’ll help with the searching the outer objects for the relevant object.

If I’m reading this right this will be a bit more of a challenge, as the post code and country is outside of the places array, so you can’t use the JavaScript find or filter functions (which only works against arrays).

Make sure you copy the response fully. I need to know how the response starts and whether it really starts with an object, or if it actually is an array which I would have thought it should be. It just doesn’t look right at all.

Use a JSON validator if necessary.

Can you please confirm if it is possible for a post code and country to have multiple places in the response. Places is an array, so I’m guessing it could have multiple places? If this is the case, then you should provide a sample response with a record that has multiple places so the logic can be tested properly.

@michaelderekjones Many thanks for the response and apologies for the indentation not being perfect, as I am new to the forum and learning a lot of things the “Hard Way” :slight_smile:
I have simplified the JSON structures a bit and sharing with you again.

[
 {
   "Country": "us",
   "Postal Code": "90210",
   "Place Name": "Beverly Hills"
 },
 {
   "Country": "us",
   "Postal Code": "12345",
   "Place Name": "Schenectady"
 },
 {
   "Country": "ca",
   "Postal Code": "B2R",
   "Place Name": "Waverley"
 }
]

Also, I tried to code it myself with my limited Knowledge and it seems to be working as well with the JSON above. Could you please take a look at my Code and suggest a better way of doing it? Many thanks in advance!

let Country = pm.variables.get(“country”);

let Postal_code = pm.variables.get(“postal-code”);

let Place_name = pm.variables.get("place_name");
pm.test("Test 2 - WITH IF ELSE CASE - Verify in Response - \"Place Name\" for each input \"Country\" and \"Postal Code\"", () => {

let jsonData = pm.response.json();
console.log(jsonData); 

if ((Country === "us") && (Postal_code === '90210'))
{
    console.log("COUNTRY IS " + Country);
    console.log("Postal_code IS " + Postal_code);
    console.log("Place Name IS " + Place_name);

    pm.expect(Place_name).to.be.eql('Beverly Hills');
    console.log("US 90210 TRUEEEEEE");
    } else{pm.expect(Place_name).not.to.be.eql('Beverly Hills');}
if (((Country === "us") && (Postal_code === '12345')))
        {
            console.log("COUNTRY IS " + Country);
            console.log("Postal_code IS " + Postal_code);
            console.log("Place Name IS " + Place_name);
            pm.expect(Place_name).to.be.eql('Schenectady');
            console.log("US 12345 TRUEEEEEE");    
        } else{pm.expect(Place_name).not.to.be.eql('Schenectady');}
 if (((Country === "ca") && (Postal_code === 'B2R')))
        {
            console.log("COUNTRY IS " + Country);
            console.log("Postal_code IS " + Postal_code);
            console.log("Place Name IS " + Place_name);
            pm.expect(Place_name === 'Waverley').to.be.true;
            console.log("CA B2R TRUEEEEEE");    
        }else{pm.expect(Place_name).not.to.be.eql('Waverley');}
});

The variables on the Top of the Code are coming from my Pre-Script, where I read the JSON File as:

pm.variables.set("country", pm.iterationData.get("Country"));

pm.variables.set("postal-code", pm.iterationData.get("Postal Code"));

pm.variables.set("place_name", pm.iterationData.get("Place Name"));

Let me know if this makes more sense to you now? Sorry about being unclear earlier :slight_smile:
Have a gread day!

I don’t understand what you are trying to achieve with those IF statements.

Each iteration can only have a single country, post code and place name.

It runs one iteration per line in the CSV file. pm.iterationData only contains the information from that particular line.

All you need to do is search the response for the object with the desired country and postal code. You can search on both at the same time.

The test then validates that you have found an object that satisfies that criteria, that the search is not undefined, and you then assert that the place name is correct.

Your assertions are still not checking the actual response. Your assertions are only looking at data from the CSV file.

Consider the following approach…

// step 1, define the country and post code for the search, plus the place name for the assertion
// Also used to customize the test case name
let Country = pm.variables.get("country"); // "us"
let Postal_code = pm.variables.get("postal-code"); // "90210"
let Place_name = pm.variables.get("place_name"); // "Beverly Hills";

// step 2 - parse the response
let response = pm.response.json();

// step 3 - search the response for the country and post code.
let search = response.find(obj => obj.Country === Country  && obj['Postal Code'] === Postal_code);

// step 4 - test that the search found an object, and that the place name matches the entry from the CSV file.
pm.test(`${Country} / ${Postal_code} = ${Place_name} `, function () {
    pm.expect(search).to.not.be.undefined
    pm.expect(search['Place Name']).to.eql(Place_name);
});

The test uses a technique called string literals to customize the test case name, so when this iterates over 20-30 lines in the CSV files, it becomes a bit easier to find out which one actually failed.

For example…

image

Hello again @michaelderekjones . Many thanks for the response. The IF statements didnt look nice, which is exactly why I asked your help in that, to make it look better :slight_smile: .
I just executed the Code and got the following error
“response.find is not a function”.
Could you please take a look? Many thanks in advance!

What does your actual response look like. I’m guessing its not exactly the same as the simplified JSON you provided in your previous post.

The JavaScript Find function only works against arrays. So the problem is most likely that the top level of the JSON response is not an array so response.find is accurately telling you that its not a valid function.

Looking nice\better and actually working code are two different things. Your IF statements and assertions were using incorrect logic and were not targeting\testing the actual response.

Which is why its always useful to take a step back and write down the steps that your script needs to take, so others can understand your logic (colleagues, people on forums, etc). Then write the code for each step.

You can then re-factor and make it look “nice” after you get it working.

True, I am using the Simplified JSON this time. It just doesnt run.


image

Would the logic you provided work with the simplified JSON I provided? Just asking?

How are you using the simplified JSON, surely the API will return what it will return (or are you in control of the API?)

Please console log the response for “API test 2”, and please share that with us.

Or send a single request using the web application\GUI, and share the response from there. The response format should be the same whether its run from Newman or the Web\Desktop application.

Please copy and paste and use the pre-formatted text option. (Please don’t use a screenshot).

Here is the Response and Console Logs using the Simplified JSON. API Test 2 Copy is same as API Test 2, so please dont be surprised. The Test you mentioned didnt execute at all due to “response.find” Error I mentioned earlier.

→ API Test 2 Copy
  ┌
  │ 'Country Code From PRE_REQUEST is us'
  │ 'Postal Code  From PRE_REQUEST is 90210'
  │ 'Place Name  From PRE_REQUEST is Beverly Hills'
  â””
  GET http://api.zippopotam.us/us/90210 [200 OK, 905B, 523ms]
  âś“  Status code is 200
  ┌
  │ 0
  â””
  âś“  Test if Response time is less than 1s
  5â „ TypeError in test-script
→ API Test 2 Copy
  ┌
  │ 'Country Code From PRE_REQUEST is us'
  │ 'Postal Code  From PRE_REQUEST is 12345'
  │ 'Place Name  From PRE_REQUEST is Schenectady'
  â””
  GET http://api.zippopotam.us/us/12345 [200 OK, 905B, 161ms]
  âś“  Status code is 200
  ┌
  │ 0
  â””
  âś“  Test if Response time is less than 1s
  7â „ TypeError in test-script

→ API Test 2 Copy
  ┌
  │ 'Country Code From PRE_REQUEST is ca'
  │ 'Postal Code  From PRE_REQUEST is B2R'
  │ 'Place Name  From PRE_REQUEST is Waverley'
  â””
  GET http://api.zippopotam.us/ca/B2R [200 OK, 899B, 159ms]
  âś“  Status code is 200
  ┌
  │ 0
  â””
  âś“  Test if Response time is less than 1s
  9â „ TypeError in test-script
  

 5.  TypeError                response.find is not a function
     iteration: 1             at test-script
                              inside "API Test 2 Copy"
7.  TypeError                response.find is not a function
     iteration: 2             at test-script
                              inside "API Test 2 Copy"
9.  TypeError                response.find is not a function
     iteration: 3             at test-script
                              inside "API Test 2 Copy"

Where is the response in what you just posted?

I need to see the JSON response from the GET request.

All I can see is some console logs for some of the variables. (Which looks like the CSV data file is being read ok, so I guess that is something).

Console log the response, so we can see the structure.

// step 2 - parse the response
let response = pm.response.json();
console.log(response);

I just looked up the The Zippopotam.us API.

It’s a really basic GET request, which returns data like the following…

{
    "post code": "90210",
    "country": "United States",
    "country abbreviation": "US",
    "places": [
        {
            "place name": "Beverly Hills",
            "longitude": "-118.4065",
            "state": "California",
            "state abbreviation": "CA",
            "latitude": "34.0901"
        }
    ]
}

Therefore this can be tested with a simple assertion. No need to use find.

let Country = pm.variables.get("country");
let Postal_code = pm.variables.get("postal-code");
let Place_name = pm.variables.get("place_name");

console.log(Country); // "United States"
console.log(Postal_code); // "90210"
console.log(Place_name); // "Beverly Hills";

let response = pm.response.json();

pm.test(`${Country} / ${Postal_code} = ${Place_name} `, function () {
    pm.expect(response['post code']).to.eql(Postal_code);
    pm.expect(response.country).to.eql(Country);
    pm.expect(response.places[0]['place name']).to.eql(Place_name);
});

The Country, Postal Code and Place Name must match otherwise the test will fail.

Please note. The Country is “United States”, not “us”. It’s “place name”, not “Place Name”. Case sensitivity matters.

I still have no idea if a postal code can have more than one place (which would break this code).

1 Like

Thank you very much. It worked. Youre absolultely right. Just to make it more matching the requirements from the Test Data(us, ca) to the Response(United States, Canada) respectively, I manipulated the Country as “United States” and “Canada”, as:

if (Country === "us"){ Country = "United States"}

if (Country === "ca"){ Country = "Canada"}

before feeding it to the Test. So the Final Test looks like this:

let Country = pm.variables.get("country");
let Postal_code = pm.variables.get("postal-code");
let Place_name = pm.variables.get("place_name");

console.log(Country); // "United States"
console.log(Postal_code); // "90210"
console.log(Place_name); // "Beverly Hills";

let response = pm.response.json();

if (Country === "us"){ Country = "United States"}
if (Country === "ca"){ Country = "Canada"}

pm.test(`${Country} / ${Postal_code} = ${Place_name} `, function () {
    pm.expect(response['post code']).to.eql(Postal_code);
    pm.expect(response.country).to.eql(Country);
    pm.expect(response.places[0]['place name']).to.eql(Place_name);
});

Please let me know your thoughts?

Can’t you assert on the country abbreviation key that is available in the response instead.

Maintaining a link between the country and abbreviation will probably make this brittle.

What happens if the country is something other than United States or Canada.

That way, the only thing you need to do is make the value in your CSV file uppercase, or make it uppercase in your script.

JavaScript String toUpperCase() Method (w3schools.com)

1 Like

I thought of that too. Actually I have been given the Testdata as a CSV/JSON and I have to abide by it, and also what needs to be verified. I can sense that it could be a Bug, as the Response from API shows full name of the Country but the Test Data expects the Country Name to be an abbreviation. Thats why I just translated it into my Logic and kept Reponse and Test Data intact, otherwise we’ll have a Mismatch. I would have to present it and would know only then, if it is actually as a Problem or not :smiley: . I would present this as a known issue. One thing I have understood so far is that the Country could either be United States or Canada and nothing else.
But I am extremely thankful to you for your Time and Help. That has been very kind of you!

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.