Checking 3 states of an array with IF/Else statement

Array has 3 potential states and im using an IF/ELSE statement to check states before running my tests

I need some guidance, i have the below if/else statement at the collection level of my test suite. There are several endpoints in the collection and all share the same json structure but depending on the endpoint, an array can have 3 states (populated, empty or not present). I need a way of specifying that the array is populated without checking for a specific object, just that it has data in it.

pm.test("Filters - Category array is correct", function () {
        let responseJson = pm.response.json();
    if (responseJson.widget.data.filters === undefined ) {
        pm.expect(responseJson.widget.data.filters).to.be.undefined
        console.log("Filters array is not present");
    } else if (responseJson.widget.data.filters.length == 0) {
       pm.expect(responseJson.widget.data.filters).to.be.empty
        console.log("Filters array is empty")
    } else (responseJson.widget.data.filters === true)
    pm.expect(responseJson.widget.data.filters[0].category).to.eq('category');

My issue is that for the else, its running at the same time as the else if because they are both correct, the filter array is empty but still present so the test is failing because the ‘category’ object isnt present.

Is there a way that i can write the else to be something like } else (responseJson.widget.data.filters === populated) i know thats not a function but its the only way i can really explain what my desired outcome is!

Thanks!

Have 3 IF statements. One for each state. 1 IF, 2 ELSE IF’s.

Have the IF statement check the URL for the request instead of the response, and then run the appropriate test out of the 3.

The final ELSE at the end should cause the test to fail (as it means one of the expected states haven’t been triggered). It’s your catch for when none of the states have been met.

I would personally embed the test within the IF statement instead of having the test case wrap around the multiple IF statements.

You could also consider using the JavaScript switch case functionality.

The following is a simple example.

let testName = "Missing Lastname";


switch(testName) {
  case "Missing Firstname":
    console.log("missing firstname");
    break;
  case "Missing Lastname":
    console.log("missing lastname");
    break;
  default:
    console.log("something else");
}

You can retreive the URL as mentioned previously, then have a case for each URL with its own specific test.

Hey Mike,

Thanks for the assist! I have about 60 other endpoints that would need to included in the IF statement so i was hoping there would be a way to do this at collection level so that it filters down to the rest of them when running the collection as a whole.

Do you know of a way to have the statements check that the array has objects within it? Or even a way that i can structure the else statement to check that specific objects are present int he array? I have its the only part blocking me from getting this working.

Appreciate the help.

Thanks

Your tests within the IF and ‘else If’ blocks will always be true, as they will only ever get triggered if the IF statement is true. If the IF statements aren’t triggered then the tests should never run, which defeats the purpose of the tests.

You should always try and make your tests fail, which would not be possible.

You are testing for 3 scenarios, so at a minimum you need an IF, two ELSE IF’s and a final ELSE that ensures that you capture any false positives. To ensure each request is satisfying at least one of the scenarios.

Put your specifics test within each of those statement blocks. A separate test for each scenario rather than a test block that covers all of the IF statements.

The problem will still be that your IF statements will always make the tests pass.

I don’t particularly like dynamic tests. (Personal preference).

Ideally, you should be in control of your test data, and an API should return exactly the same response each and every time.

In your situation, you are trying to cut down on code which is exactly what the code tabs on the folder and collection are for.

You could potentially make use of environment or collection variables to specifically list which tests should run against which end point. A simple array of endpoints dictating which scenarios should run.

{
    "Scenario1": ["endpoint1", "endpoint2"],
    "Scenario2": ["endpoint3", "endpoint4"],
    "Scenario3": ["endpoint1", "endpoint4"]
}

You only need to maintain that variable if you make changes or add endpoints.

You can then retreive that variable in your pre-request script alongside the storing the current URL as a variable.

You can then have an IF statement checking if the current URL is in the array for any of the scenarios then run the relevant tests for that end point.

You still need that final ELSE to capture any requests that don’t trigger one of the expected scenarios.

You could also reverse that JSON example, and have each endpoint listed with an array of what scenarios should run for each endpoint.

Thanks for that solution, i have implemented that suggestion and its working now! :slight_smile:

I have also taken note of the your comment around having control of the test data that is being returned and raised a ticket with the Dev team to amend the behaviour of the endpoint so that it only returns 2 states so that in the future i can cut down a bit more of the code.

As always, thanks for the help on this one Mike

2 Likes