Test fails when run manually but passes in collection tests

Your question may already have an answer on the community forum. Please search for related topics, and then read through the guidelines before creating a new topic.

Hereā€™s an outline with best practices for making your inquiry.

My question:
Iā€™m creating my first tests around a graphQL collection. I started by creating two simple tests to ensure that a query executed successfuly and did not contain an ā€œerrorsā€ element.

I tested this against a single query by modifying the query parameters to generate an error and ran the two tests ā€“ I got a test failure as expected.

When I run the entire collection using these same two tests, that particular query passes even though it failed when tested manually.

Details (like screenshots):
Hereā€™s the individual query, with query parameters. It runs fine with valid parameters:

  query GET_CLIENT_NAMES($id: ID!, $asOfDate: ID!) {
    data: GetClient(id: $id, asOfDate: $asOfDate) {
      displayName
    }
  }
Query details changed for privacy
{
    "id": "XXXX",
    "asOfDate": 1653980400,
    "portfolioId": "XXXX:1653980400"
}

Iā€™ve modified the parameters so that they are invalid and will generate an error.

These are the two query tests:

pm.test("Ensure 200 status code", function() {
    pm.response.to.have.status(200);
})
pm.test("Response does not contain errors response", function () {
    pm.expect(pm.response.text()).to.not.include("errors");
});

And the second (errors) test fails as expected:
Sorryā€¦ Iā€™m limited in the number of images I can include :=((
image|690x411

Iā€™ve added those same tests to the collection:

I have no variables defined for the collection ā€“ theyā€™re all set on the individual queries for the moment. When I run the collection, that query passes:

How I found the problem:
Just running some basic tests to make sure I understood how graphQL testing works in Postman.

Iā€™ve already tried:
Searched for relevant answers here.
Tried changing variable values.

OK; hereā€™s that other image showing the test failure when the individual query is run.

Hi @jesii7

Im trying to follow your question. I think what you are saying is;

Even though the GraphQL query returns an error, your Postman call is passing with a 200. Is that correct?

If so, I had this same issue recently and after speaking to a developer he told me that GraphQL works differently to REST.

REST will fail with a response code (ie 400, 401, 500 etc), whereas GraphQL passes the information back as part of the query which ā€œtechnicallyā€ is not a failure as it passed a result back to the user. The fact that it passes information about an error does not trigger a failed response code.


If Iā€™m way off base, let me know and Iā€™ll have another read of the above.

Thanks for the reply, @w4dd325 ā€“ my question is different than that.

Youā€™re right that graphQL mostly doesnā€™t return the HTTP status codes that we use for REST; they can return status 200 (when the query doesnā€™t completely bomb out due to internal errors) and still show errors in the body of the response, as in:

,"errors", {... lots of information here}

Fortunately, Postman provides a way to test the response, which is what Iā€™ve done with this, the second test in my test script:

pm.test("Response does not contain errors response", function () {
    pm.expect(pm.response.text()).to.not.include("errors");
});

In a nutshell, if graphQL gives me a 200 response, but also offers that ā€œerrorsā€ element, then thatā€™s an error and the test cause a failure.

It correctly fails when I run the test manually;
It incorrectly passes the test when run as part of the collection.

HTHā€¦jon

@jesii7 Looking at the following.

Requests and Responses in GraphQL - GraphQL (dgraph.io)

The response should be a JSON file.

It sounds like the errors field only appears if there is an error, so all you really need to do is check for the existence of that field. It looks like ā€œerrorā€ will be at the top level in the response so the following should work.

const response = pm.response.json();

pm.test(`Response does not include errors`, () => {
    pm.expect(response).to.be.an('array');
    pm.expect(response).to.not.include('errors');
});

Thanks, Mikeā€¦ but that doesnā€™t work. response is not an array; pm.response.text() is also a valid function which returns the text value (essentially JSON.stringified()) which then works with a simple includes test. The test I wrote works (i.e., catches the error) when executed manually against a single query; it fails (i.e., passes the error) when executed as part of a collection.

I havenā€™t fed variables into GrahpQL before as you show in your screenshot.

But it could be this that the runner doesnā€™t like (running out of ideas).

Have you tried adding the variables as collection level variables; So {{variable}} instead of $variable, with values here;
image


or as a CSV file to feed in for the collection runner?
image

@jesii7

According to the API spec, the responses are JSON, so although you could use pm.response.text(), I find it easier to store the response in a Javascript array to manipulate and target elements.

Have you tried the test I posted, as it should be able to sit alongside your other tests\code without affecting them.

Alternatively, can you stick pm.response.text() into the console, and then show what its returning.

You might also want to consider defining the response first, writing it to the console and checking it.

const response = pm.response.text();
// console.info(response);

pm.test("Response does not contain errors response",  () => {
    pm.expect(response).to.not.include("errors");
});

Looking at the test script examples.

Test script examples | Postman Learning Center

It would appear that the recommendation is to parse the response where possible, but you can use response.text() as an alternative if you canā€™t parse the data because its not ā€˜formatted as JSON, XML, HTML, CSV, or any other parsable data formatā€™.

In this situation, you can parse the response body into Javascript, so I would recommend that as the first step.