Asserting over a dynamic boolean

i have a dynamic boolean in my code
i want to assert over the response body
i used the following:-

var trackExplicitLyrics = pm.collectionVariables.get("explicitLLanguageIdBoolean") == true
pm.test("Explicit language field modified successfully", function () {
    pm.expect(jsonData.tracks[0].explicit).to.eql(trackExplicitLyrics);
  
});

When the boolean in the response is true, i rcv the following error
| AssertionError: expected true to deeply equal false

When the boolean in the response is false, the test passes

How can i write a test that will always pass as long as the response body returns the correct boolean that was set in the pre-request script
thanks

can anyone help me please?

Hey @hannahbroch :wave:

Could you share an example of the response body which shows that true/falue value, please?

Can you expand on what you would have in the pre-request script that would be changing the boolean value? Not sure I get that part.

@danny-dainton

thanks

response body sample:-

{
    "labelId": 293312,
    "labelName": "Identity - CHILD",
    "discNumber": null,
    "trackLength": null,
    "channels": null,
    "sampleRate": null,
    "bitDepth": null,
    "bitrate": null,
    "trackVendorId": null,
    "isrc": null,
    "version": null,
    "copyrightC": null,
    "copyrightP": null,
    "description": null,
    "languageId": 175,
    **"explicit": false,**
    "lyrics": null,
    "playingCount": 0,
    "appleId": null,
    "priceTierId": null,
    "rdioId": null,
    "previewStartSeconds": null,
    "totalSales": 0.0,
    "image": null
}

prerequest script:

pm.collectionVariables.set("explicitLanguage1", pm.variables.replaceIn('{{$randomBoolean}}'));

Hey @hannahbroch,

I still don’t really understand why the pre-request script is being used to set a variable for the boolean value :thinking:

Do you not want to create the assertion based on the response body and the explicit property value?

If you’re looking at checking that the response contains that property and it’s a specific value, you could do this:

Response:

{
    "tracks": [
        {
            "labelId": 293312,
            "explicit": true
        }
    ]
}

Test:

let jsonData = pm.response.json();
pm.test("Explicit language field is true", function () {
    pm.expect(jsonData.tracks[0].explicit).to.be.true;
});

It’s difficult to see/know what you’re actually testing for here. I don’t understand the use case of checking the response against a random variable value created in a pre-request script.

@danny-dainton
in the request, the user has the option to select true or false
i want to be able to test both options at random, sometimes they choose true and sometimes they choose false

Wouldn’t you want to test the actual response you’re going to be receiving from the user, rather than have a test that’s not really checking that?

Could you not add some logic in the Tests to test for a certain value based on the response.

You can do something like this:

let jsonData = pm.response.json();

if (jsonData.tracks[0].explicit) {
    pm.test("Explicit language field is true", function () {
        pm.expect(jsonData.tracks[0].explicit).to.be.true;
    });
}
else {
    pm.test("Explicit language field is false", function () {
        pm.expect(jsonData.tracks[0].explicit).to.be.false;
    });
}

Or have check that it’s either true or false and add the value to the test result :

let jsonData = pm.response.json();

pm.test(`Explicit language field is true or false - Value is ${jsonData.tracks[0].explicit}`, function () {
    pm.expect(jsonData.tracks[0].explicit).to.be.oneOf([true, false]);
});

There are lots of things you could do and assert against.


If you wanted to test the dynamically changing response value, you can create the same variable in the pre-request script:

// _.sample() is a Lodash function that randomly picks a value
pm.collectionVariables.set('explicitValue', _.sample([true, false]));

And add that variable to the request payload body:

{
    "tracks": [
        {
            "labelId": 293312,
            "explicit": {{explicitValue}}
        }
    ]
}

thank you very much, this is very helpful

1 Like

Personally, I really don’t like the concept of dynamic tests.

You should be in control of your test data, and the request\response and associated assertion should be the same every time.

Dynamic tests can be brittle and lead to many false positives (and vice versa).

Therefore, you should have two separate requests (at the minimum).

One for true, one for false, and potentially one for an invalid option that should produce an error of some sort.

This really comes down to what you are trying to test.

You can either create two requests for this to the same end point with the appropriate tests, or you could potentially use a pre-request script and tests tab to loop over the options using the array shift() method and setNextRequest.

I agree - It’s the feelings I had when I was trying to get my head around the use case and what was actually being tested.

Trying to do everything in a single test, made me feel uneasy. I’m not a fan of dynamic tests. They should be deterministic and checking the same thing each time, so that you know that when it doesn’t fail - you need to be looking at that.

Checks like these are just little change detectors, alerting you to a change in the known behavior.

Here is a basic example of using setNextRequest.

I’m running this against Postman Echo with a very basic request body.

image

With the following in the pre-request scripts…

if (!pm.collectionVariables.get("booleans")) {
    pm.collectionVariables.set("booleans", JSON.stringify([]));
}

let array = JSON.parse(pm.collectionVariables.get("booleans"));

if (array.length === 0) {
    array = [true, false];
}

pm.test("boolean array is not empty", () => {
    pm.expect(array).to.be.an("array").that.is.not.empty;
});

var currentBoolean = array.shift();
console.log(currentBoolean);

pm.collectionVariables.set("bool", currentBoolean);
pm.collectionVariables.set("booleans", JSON.stringify(array));

This would probably answer your original question, as you can use the bool variable for your assertion and it would keep resetting the Boolean array, so it won’t be random, but will go, true, false, true, false, indefinitely.

However, to loop though both options, you can do this using the following in the tests tab.

var array = JSON.parse(pm.collectionVariables.get("booleans"));

var expectedResponse = pm.collectionVariables.get("bool");

var actualResponse = pm.response.json().data.Boolean;

pm.test(`response boolean = ${expectedResponse}`, () => {
    pm.expect(actualResponse).to.eql(expectedResponse); 
});

if (array.length > 0){
    postman.setNextRequest("setNextRequest Loop"); // Change to what your request name is

} else {
    postman.setNextRequest(null);
}

And the results are in…

image

One iteration, which has run the same request twice with a matching test.

Please note: You need to run this through the collection runner as setNextRequest() only works with the runner.

On a side note, you would normally get your test to fail which I can’t do as I’m only testing what I sent, so it will always pass.

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