Saturday, April 7, 2018

Adding Postman Assertions

This week, we'll be talking about adding assertions to our Postman requests.  In last week's post, we discussed what various API request responses mean, and how to write assertions for them in Postman requests.  Now we'll be adding some more assertions that will test our requests more fully. 

We will be using the Postman collection that we created two weeks ago, so if you haven't yet created that, you may want to set it up before you continue. 

The first type of assertion we'll discuss is the Response Time assertion.  This verifies that the response to an API request is returned within an acceptable amount of time. Let's say that the product owners of the Swagger Pet Store have decided that their end users should be able to add a new pet to the store in under one second.  We'll add an assertion for this to our Add Pet request.  Click on the Add Pet request in the collection list on the left of the screen so it will open up in the main window. Then click on the "Tests" tab.  You should already have the Response Code assertion that you added last week.  Click underneath that assertion, and then click on the "Response time is less than 200 ms" code snippet on the right.  This will be added to the Tests window:

pm.test("Response time is less than 200ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(200);
});

Currently the test is asserting that the response time should be less than 200 milliseconds.  We don't need it to be that fast, so let's change the assertion.  First, change the "Response time is less than 200ms" to be "Response time is less than one second".  This is the title of the test.  Now let's change the actual assertion.  Change the value in "to.be.below" from 200 to 1000 (this is one thousand milliseconds, or one second).  Save your request and click the Send button.  You should see in the Test Results section at the bottom of the screen that your assertion passed.  You can also look at the top of the results window and see the response time next to the response status code. 

Another helpful assertion is the Response Contains String assertion.  This simply asserts that the body of the request response has a certain string.  I often use this assertion when I am expecting an error message.  To see this in action, let's add a new negative test to our collection.  We will trigger a 500 response by trying to add a pet to the store with a non-integer id. The easiest way to create this request will be to copy the existing Add Pet request and rename it to "Add Pet With Invalid ID". (If you don't know how to copy and rename a request, see Creating a Postman Collection.) 

We have a few changes to make to this request before we add in our new assertion.  In the body of the request, we'll change the id of pet from "100" to "FOOBAR".  Because we copied this request, we already have a couple of assertions in it: one that asserts that the response code will be 200, and one that asserts that the response time is less than 1000ms.  We know that our response code won't be 200 any more, so let's change that test to read:

pm.test("Status code is 500", function () {
    pm.response.to.have.status(500);
});

We can leave the Response Time assertion as is, or we can remove it.  Now we can add in our new assertion.  Look in the snippet list for "Response body:Contains string", and click on it.  This will be added to the Test window:

pm.test("Body matches string", function () {
    pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});

Let's rename the assertion from "Body matches string" to "Error response is returned", and change the response text from "string_you_want_to_search" to "something bad happened". It's worth noting at this point that Postman assertions are case-sensitive, so you won't want to capitalize the word "Something", since it's not capitalized in the actual response.

Click the Send button and verify that you get Pass messages for both your Status Code test and for your Response Contains String test.

Now let's look at a more powerful assertion: the JSON Value Check.  We can actually assert that the values returned in a response are the values that we are expecting.  Let's look at the Get Pet request.  We are already asserting that the response code is 200, but that doesn't really tell us much.  It's possible that when we make our request that we are getting the wrong pet in the response!  We'll want to assert that we are getting the right pet back without having to physically look at the response. So we'll add a JSON Value Check.  Click below the Response Code assertion, and then look for the code snippet called "Response body: JSON value check". Click on this snippet.  This will be added to your test window:

pm.test("Your test name", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(100);
});

Change the test name from "Your test name" to "Body contains pet id". Notice that the next line of code creates a variable called jsonData. This is the parsed version of the JSON response. On the third line, we'll change "jsonData.value" to "jsonData.id". This is because we want to find out what the id of the response is.  Finally, we don't need to change the value in "to.eql", because we were looking for an id of 100, and that's what it's already set to. When you are done making your changes, the assertion should look like this:

pm.test("Response contains id", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.id).to.eql(100);
});

Save your request changes and then click the Send button.  Both your Response Code assertion and your JSON Value Check tests should pass.

You may have noticed that there are other ids in the body of the Get Pet response:

{
    "id": 100,
    "category": {
        "id": 1,
        "name": "Cat"
    },
    "name": "Grumpy Cat",
    "photoUrls": [
        "https://pbs.twimg.com/profile_images/948294484596375552/RyGNqDEM_400x400.jpg"
    ],
    "tags": [
        {
            "id": 1,
            "name": "Mixed breed"
        }
    ],
    "status": "available"
}

 How would we assert on the category id or the tag id?  We do this by parsing through the JSON response. In order to demonstrate this, copy the test you just created, and edit it to look like this:

pm.test("Response contains category id", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.category.id).to.eql(1);
});

We've changed the test name in the top line of the code to reflect what we are actually asserting.  The second line of code remains the same. In the third line of code, we've changed "jsonData.id" to "jsonData.category.id". This means that instead of looking at the id, we are looking at the category section, and then at the id within that section. Finally we changed the value that we were expecting from 100 to 1. 

Save your request and click the Send button again. Now you should see all three assertions on the request pass.

Now that you know how to create assertions, you can go through all of the requests in your Pet Store collection and add your own! You may have noticed that your POST and PUT requests return the pet in the body of the response, so you can add similar assertions to those requests.  You'll definitely want to make sure that after you have changed your pet data with the PUT (Update Pet) request, the data you get back from your GET (Verify Update Pet) request has the updated information that you are expecting. 

This is just the beginning of what you can do with assertions!  Next week, we'll take a look at how to set variables and use them in both your requests and your assertions. 

No comments:

Post a Comment

A Gentle Introduction to Session Hijacking

We all know that Session Hijacking is bad, and that we should protect ourselves and our applications against it.  But it's difficult to ...