Validate data format of parameters

I am testing an API which allows users to access current weather data for any location on Earth.

The parameters involved are:
q (city name)
appid (unique API key)
units (units of measurement)
lang (language)

All of these parameters have a String data format. How can I validate the data format of these params?

Below is what I have constructed in Postman. I have added the params with values.

This is the response:

{
    "coord": {
        "lon": 151.2073,
        "lat": -33.8679
    },
    "weather": [
        {
            "id": 801,
            "main": "Clouds",
            "description": "few clouds",
            "icon": "02n"
        }
    ],
    "base": "stations",
    "main": {
        "temp": 21.68,
        "feels_like": 21.84,
        "temp_min": 19.62,
        "temp_max": 23.17,
        "pressure": 1014,
        "humidity": 74
    },
    "visibility": 10000,
    "wind": {
        "speed": 3.6,
        "deg": 50
    },
    "clouds": {
        "all": 20
    },
    "dt": 1675779647,
    "sys": {
        "type": 2,
        "id": 2002865,
        "country": "AU",
        "sunrise": 1675797783,
        "sunset": 1675846539
    },
    "timezone": 39600,
    "id": 2147714,
    "name": "Sydney",
    "cod": 200
}

We can see that only the city (q param) is in the body (name). I donā€™t see the other params as they seem to be background/general settings.

I have used this Test to validate the string format of name (q) property which passes:
pm.test(ā€œData format is stringā€, () => {
const responseJson = pm.response.json();
pm.expect(responseJson.name).to.be.a(ā€˜stringā€™);
});

I have also tried the below Test which fails (I get this message: Data format is string | AssertionError: expected [ { key: ā€˜qā€™, value: ā€˜Sydneyā€™ }, ā€¦(3) ] to be a string):
pm.test(ā€œData format is stringā€, () => {
console.log(pm.request.toJSON().url.query)
pm.expect(pm.request.toJSON().url.query).to.be.a(ā€˜stringā€™);
});

Please advise on how to validate the data format of the params.

Please use the preformatted text option in the editor when pasting code to stop everything being aligned to the left.

You can get to the body of the request using the following method.

const request = JSON.parse(pm.request.body.raw);

I donā€™t really get the point of the test though as this is testing the request, not the response.

Your provided code gave me this error:
There was an error in evaluating the test script: SyntaxError: Identifier ā€˜requestā€™ has already been declared

Iā€™m not sure what the above is trying to achieve. I think I know how to extract from the body. But, the point is that I want to validate the data format of the params which are all string. Since 3/4 are not in the response, is this what you mean by testing the request?

Ok, just re-read your post and realised its the URL parameters, not the body you want.

The variable that you return is an array of objects.

You could wrap the test in a loop.

let requestParams = (pm.request.toJSON().url.query);

requestParams.forEach(param => {

    pm.test(`request parameter ${param.key} value is a string`, () => {
        pm.expect(param.value).to.be.an("string");
    });
    
});

What I meant in my response is surely you already know what data is being supplied in the request. I canā€™t see the benefit of checking if they are strings.

This looks to be what I want as the results clearly state that each param is a string based on the values passed. I tested with other types in place of string and it does check if the values match the formats. Thank you very much!

I know the forEach part is the loop, but Iā€™d also like to know how to break this down so that each param is tested individually?

The variable is an array, so you need to target the array elements using its index. (Array indexes start at 0).

For example.

let q = requestParams[0].value;

Or, you can use the JavaScript find function to find the object with a certain key, and then the value element for that object.

let q = requestParams.find(obj => obj.key === "q").value;

The Params seem to be returned in order, so the first method using the index should work, otherwise if you canā€™t guarantee the order then I would use the find method.

Not sure what you mean by ā€œso that each Param is tested individuallyā€.

That loop is testing each parameter in the request. It is testing the Params individually. Itā€™s done that way so I donā€™t have to repeat the code 4-5 times using the array index.

I meant testing the params separately, so writing out the code for each param. I just wanted to know how to do it on an individual basis if there was only 1 param. But yes, it makes sense to do the loop as it is more efficient, so I will implement that.

Below Iā€™ve wrote out the code for both loop/index tests for peopleā€™s benefit.

//declare identifier to reference in tests
let requestParams = (pm.request.toJSON().url.query);

//index method to test params individually
let q = requestParams[0].key;
    pm.test(`request parameter ${q} is a string`, () => {
        pm.expect(q).to.be.an("string");
    }); 

let appid = requestParams[1].key;
    pm.test(`request parameter ${appid} is a string`, () => {
        pm.expect(appid).to.be.an("string");
    }); 

let units = requestParams[2].key;
    pm.test(`request parameter ${units} is a string`, () => {
        pm.expect(units).to.be.an("string");
    }); 

let lang = requestParams[3].key;
    pm.test(`request parameter ${lang} is a string`, () => {
        pm.expect(lang).to.be.an("string");
    }); 

//loop method to test all params at once
requestParams.forEach(param => {
    pm.test(`request parameter ${param.key} is a string`, () => {
        pm.expect(param.value).to.be.an("string");
    }); 
});

Results:
PARAM FORMAT VALIDATION RESULTS - INDEX AND LOOP

Thank you very much for your assistance Mike. :slight_smile:

That is testing that the key is a string, not the value. Is that what you really wanted?

All keys are strings. They canā€™t be any other type as far as Iā€™m aware. The value can.

Did you try and make the test fail?

Marking your own post as the answer is a bit cheeky. :slight_smile:

I think it is the value that I want to validate then as my requirement is vague (the topic). I know how to set this (change key to value).

To get it to fail I changed the format to other types like integer.

I set my response as the solution just so that other people can get what they want easily as it shows both solutions with the results. Sorry, I didnā€™t mean anything by it. I did actually go through and set your posts as solution and then my post, stupidly thinking that all relevant ones would be the solution :person_facepalming:. Your solution is in my post anyway, but I have set your post as the solution :grin:. Thanks again.

1 Like

No problem, a good rule of thumb with any automated test is to make it pass and then make it fail to ensure you arenā€™t getting a false positive.

1 Like