Skip to content

Instantly share code, notes, and snippets.

@zec4o
Last active November 30, 2023 02:28
Show Gist options
  • Save zec4o/f39735f81c730c7f399f726b6ca066e0 to your computer and use it in GitHub Desktop.
Save zec4o/f39735f81c730c7f399f726b6ca066e0 to your computer and use it in GitHub Desktop.

Automated Rest API Testing with Postman πŸš€πŸ§‘πŸΌβ€πŸš€

In this guide, you will not only find an introduction to requests in Postman but also how to test them in an automated way.

References πŸ“–

List of key study sources for what I'm going to cover here:

What are HTTP requests in practice? πŸ€“

In practice, HTTP requests are calls made by the client to the server, and depending on the method, they expect a response.

The most commonly used methods (or verbs, as they are commonly called) are:

  • GET - The GET method should return the data from the endpoint to which the request was made.
  • PUT - The PUT method aims to change/edit, in a way that overwrites the data of the request's endpoint.
  • PATCH - Unlike the PUT method, PATCH only changes the fields specified in the request body, without completely overwriting the endpoint.
  • POST - The POST method creates a new resource on the server. In this method, the request body will carry the data to be transmitted to the endpoint.
  • DELETE - The DELETE method, as the name suggests, removes a specific resource.

With this information, we can start our journey on the web behind the scenes!

What are we going to use? πŸ˜πŸ’»

For our examples, I will be using, in addition to the Postman tool, the fake API JSONPlaceholder.

This API has the following endpoints:

  • /posts - 100 posts
  • /comments - 500 comments
  • /albums - 100 albums
  • /photos - 5000 photos
  • /todos - 200 todos
  • /users - 10 users

Let's get practical!

Organizing your requests in Postman πŸ’»πŸ§‘πŸΌβ€πŸš€

In terms of organization, I like to follow the following "breadcrumb": Workspace > Collection > Request

  • In our case, I created the Workspace "API Testing - JSONPlaceholder":

    creating a postman workspace

  • To organize the view, I created collections for each API endpoint:

    creating a postman collection

  • Finally, I created the request within the collection for the endpoint I want to call.

    creating a postman request

Creating your first requests in Postman:

In this section, we will perform all the most common requests on the /posts endpoint and analyze their responses.

GET on /posts βœ…

  • To make a GET request on /posts, simply enter the API link with the /posts endpoint and select the GET method.

    GET /posts

  • In this request, we can see that the GET on /posts returns a structure with several posts. These posts contain the following attributes in their respective structures:

{
  "userId": "id of the user who created the post",
  "id": "post id",
  "title": "post title",
  "body": "post body/text"
} 

POST on /posts βœ…

  • To make a POST request on /posts, enter the API link with the /posts endpoint, select the POST method, and pass the request body. Note that the post id was not passed since, in this case, the API associates the new post with the next uncataloged id. However, it is possible to pass any "id" in the request body, provided it has not been assimilated before.

    POST /posts

  • In the response body, you can see the data of the post that was passed in the request and the id of the post that was assimilated by the API.

GET on /posts/{id} βœ…

  • Much like the GET done on the /posts endpoint, the GET on /posts/{id} should return only the data of the post corresponding to the id passed in the endpoint.

    GET /posts/{id}

  • Note that in the response body, we have only the structure of the post corresponding to the id that was passed.

PUT on /posts/{id} βœ…

  • To make the PUT request on the /post/{id} endpoint, you must pass in the request body all the data that will "update" the referred id. This data will overwrite what currently exists in the endpoint.

    PUT /post/{id}

  • Note that considering the example we made of the GET request on /posts/1, you can see the difference in the content of the /posts/1 endpoint before and after the PUT.

  • In this case, it is noticed that the response body is filled only with the data passed in the request body of the PUT method (in addition to the "id" that is automatically assimilated by the API because the URL is already passing the "id" as a parameter).

Before

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

After

{
  "title": "my title",
  "id": 1
}

PATCH on /posts/{id} βœ…

  • To make the PATCH request on the /post/{id} endpoint, you must pass in the request body only the fields that will be changed in the structure of the referred id. This data will overwrite only the fields passed in the request body, unlike PUT.

    PATCH /posts/{id}

  • Also, considering the

example we made of the GET request on /posts/1, you can see the difference in the content of the /posts/1 endpoint before and after PATCH: In our case, as only "title" was passed in the request body, only it was changed in the structure.

Before

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

After

{
  "userId": 1,
  "id": 1,
  "title": "my new title",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

DELETE on /posts/{id} βœ…

  • It is simple to make a DELETE request in Postman, just select the method and, in this case, pass the "id" parameter in the endpoint. The empty response body.

    DELETE /posts/{id}

  • With the status of 200, it is noticeable that the DELETE request was successful. Thus, it can be seen that there is no response body.

What are environment variables in Postman and how to create them

Now that we know how to make requests in Postman, let's go a step further and understand how environment variables can help us in automating API tests.

  • In our case, environment variables will be extremely important to avoid repetition and rework in tests, in addition to making the view less complex.

Creating our first environment variable

For this, it is necessary to create the environment that will contain all the created variables.

  • STEP BY STEP TO CREATE ENVIRONMENT AND VARIABLE MANUALLY:

    createenvironment

Updating an environment variable based on the response of a request 🌐

To update an environment variable by assimilating certain content from the response body of the request, it is first interesting to know that tests in Postman, which can be done through the JavaScript embedded in the software, will only be executed after the request has been completed. Thus, let's go practical!

In the "Tests" tab of the request, the following code should be passed:

var **variable declared in the test that will analyze the JSON** = JSON.parse(responseBody)
pm.environment.set("pre-created environment variable", **variable that will analyze the JSON**["variable that comes in the request body"]);
  • "var" -> declares a variable in the request test.
  • "JSON.parse(responseBody)" -> analyzes the JSON present in the response body of the request.
  • "pm.environment.set" -> sets the content of the environment variable within the currently selected environment.

Using as an example the POST request on the /posts endpoint, we would like to create a variable that assimilates the "id" of the post that will be created. Thus, before everything, I must create an environment variable to assimilate the value that will be received in the response body. In our case, this environment variable will be "id_of_the_post".

This way, our code in the tests tab would look like this:

var jsonData = JSON.parse(responseBody)
pm.environment.set("id_of_the_post", jsonData["id"]);

post+variable

This can be used for various purposes, such as: Associating an authorization token from a registration request with other requests that need it, for example. In tests, a POST can be followed by a DELETE /endpoint/{id} for the "id" that was taken in the POST request. There are countless ways to use it; it depends on your needs and creativity!

With this, how to perform API tests with validations in Postman? πŸ€·πŸΌβ€β™‚οΈ

Writing test scripts in Postman is done in a very simple way, using only the validation syntax of the Chai Assertion Library present in the structure of this tool. These scripts can range from status code validations to multiple validations of cookies, response time, header content, and more.

Status code validation test

The validation test can be done using the following syntax:

 pm.test("test name", function () {
 pm.response.to.have.status(desired status);
});

test200ok

Note that, having a status that validates the status code, if it is equal to the expected one, the result is positive for the test. βœ…

Response Request Tests βœ…

  • Not much different, response body tests validate all content received in the response body, with various "asserts" covered by the "Chai Assertion Library." So when it comes to validations, the sky's the limit!

Several tests performed in a single request that will be saved for every future request:

    // Status code validations
      // Status code validation test
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});

      // Text response test of the status code
pm.test("The status code text is: OK", () => {
pm.response.to.have.status("OK");
});

  // Request header validations
      // Test to check the existence of a header.
pm.test("Content-type is present in headers", () => {
pm.response.to.have.header("Content-Type");
});

  // Performance validation
      // Response time test
pm.test("Response time is less than 150ms", () => {
pm.expect(pm.response.responseTime).to.be.below(150);
});



// Response body validations
pm.test("The response of the request was validated.", () => {
// Create a constant to parse JSON
  const jsonResponse = pm.response.json();
// Test that validates the content of a variable
  pm.expect(jsonResponse.userId).to.eql(1);
// Test that validates the type of a variable
  pm.expect(jsonResponse.userId).to.be.a("number");
  pm.expect(jsonResponse.id).to.eql(1);
  pm.expect(jsonResponse.id).to.be.a("number");
  pm.expect(jsonResponse.title).to.be.a("string");
  pm.expect(jsonResponse.title).to.eql("sunt aut facere repellat provident occaecati excepturi optio reprehenderit");
// Test that validates the number of characters in the content of a variable
  pm.expect(jsonResponse.title).to.have.lengthOf(74);
});
  • The result of these tests using the GET method on the /posts/1 endpoint of the API we are using was as follows:

image Note here that, because it has a response time greater than expected in our script, the test did not pass!

To conclude, how do we run all requests and their respective tests automatically?

  • Accessing the main folder of the collection, you can see the "run collection" button, which, when clicked, will start making the requests in the order of folder organization. Like this:

finalgif

As an extra, I explain the functionality of Monitors in Postman. πŸ–₯οΈβœ…

In addition to everything that has been covered here, creating a monitor for your collection makes it possible to:

  • Set a timer to run all requests automatically every X hours/days/weeks
  • Receive emails automatically for every error/failure in the tests.
  • Set delays between requests.
  • Choose the region of Postman servers where tests will be performed.
  • Automatically retest X times if a test fails.
  • Set a maximum timeout for requests.

monitor tests

THE END!

Thank you very much, everyone! πŸ™πŸ™

If you have any questions/feedback, feel free to contact me through my Github or Linkedin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment