DEV Community

Cover image for Beginner's Guide in Testing APIs
Hector Sosa
Hector Sosa

Posted on

Beginner's Guide in Testing APIs

Previously in Beginner's Guide to Working with APIs we learned how to work with API using different tools (Postman, cURL), we reviewed their basic nature (HTTP Methods), and discussed how to share Postman data via Collections to collaborate with others. Oversimplifying things, the last core component of API development we are missing is writing tests.

Writing tests confirm that your API is working as expected, that integrations between web services are reliable and that any new changes haven't broke anything. In Postman, you can add tests to (a) individual requests, (b) collections, and (c) folders in a collection.

Scripting in Postman

Yes, we are sticking with Postman throughout this series! It contains a powerful runtime based on Node.js. Therefore, you can run your script during 2 events in the flow:

  1. Before an HTTP Request is sent, as a pre-request script,
  2. After an HTTP Response is received, as a test-script

Depending where you add your script (requests, collections or folders), they will execute at that scoped level before and after every request and response respectively (i.e. A script added to a collection will run prior and after every request in the collection).

Test Flow in Postman

In Pre-request Scripts you can carry out pre-processing such as setting variable values, parameters, headers, and body data. However, today we'll explore How to Test APIs by using those scripts that run after an HTTP response is received.

Writing a test at the request level

Explore writing tests at the request level with our previously used Postman Collection, which has been build based on the very popular JSON Placeholder API for testing and prototyping projects.

Let's take a look at the following request: Posts > Creating a Resource. Once this POST request is opened, use the Tests tab and you can write the following test:

pm.test("Status code is 201", () => {
    const response = pm.response;
    pm.expect(response.code).to.eql(201);
});
Enter fullscreen mode Exit fullscreen mode

What is the PM object?

The pm object provides functionality for testing your request and response data. In this case, let's add a console.log(pm.response) to take a look at what we have available here:

{
  id: "1a3f0c24-76aa-46bd-b209-e9fbd2670f31"
  status: "Created"
  code: 201
  header: [25]
  stream: {}
  cookie: [0]
  responseTime: 166
  responseSize: 65
}
Enter fullscreen mode Exit fullscreen mode

Our first test checks the response's code using pm.expect(response.code).to.eql(201). However, we could also write tests for the other properties found: status, header(s), responseTime, responseSize and more.

The test method has a two parameters (a) Test name, type string and (b) a Callback function that represents an assertion. Postman tests can use Chai Assertion Library BDD syntax, which provides readable tests chaining methods to express assertions. For example: pm.expect(response.code).to.eql(201), reads as expect this code to equal this.

So what are Response Codes?

Before we dive in test assertions, let's quickly review what are response codes. HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:

  1. Information responses (100 - 199)
  2. Successful responses (200 - 299)
  3. Redirection messages (300 - 399)
  4. Client error responses (400 - 499)
  5. Server error responses (500 - 599)

Our tests indicates that we should expect an HTTP response status code of 201 which makes sense given the HTTP Request Method used POST. 201 Created is the response code sent after POST requests. Therefore, if the request succeeded, a new resource will be created as a result.

A Cheatsheet for building Tests with Postman

So let's go ahead and start testing. Here are some of the most common tests I've compiled:

/****
Test Case/Scenario 
POST: Creating a Resource
*****/

/* I find it useful to define these variables at the start */
/* Feel free to define them within the test itself */
/* Or to define additional ones */
const response = pm.response;
const responseJson = response.json();

/* Check Response Status Codes */
pm.test("Status code is 201", () => {
    pm.expect(response.code).to.eql(201);
});

pm.test("Response is successful", function () {
    pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]);
});

/* Via the responseJson variable you can check the response properties */
/* Using different assertions for value, type, length, etc... */
pm.test("The JSON response has all properties", () => {
    pm.expect(responseJson.title).to.eql('foo');
    pm.expect(responseJson.body).to.be.a('string');
    pm.expect(responseJson.body).to.have.lengthOf(3);
    pm.expect(responseJson.userId).to.be.a('number');
});

/* Calling the text method on responds is useful... */
/* to check if your response body includes 'n' string */
pm.test("Body matches string", function () {
    pm.expect(response.text()).to.include("bar");
});

/* The response also has properties you can test */
/* such as responseTime for performance testing */
pm.test("Response time is less than 200ms", function () {
    pm.expect(response.responseTime).to.be.below(200);
});

/* You can also create schemas for testing... */
/* using Tiny Validator for JSON data */
const schema = {
    "type": "object",
    "properties": {
        "title": { "type" : "string" },
        "body": { "type" : "string" },
        "userId": { "type" : "number" }
    }
};

pm.test('Schema is valid', function () {
    pm.expect(tv4.validate(responseJson, schema)).to.be.true;
});
Enter fullscreen mode Exit fullscreen mode

Once you have defined which tests you want to run for a given resource/endpoint. You can go ahead and read the results from the Test Results tab in Postman. If you need to debug a test you can also open Postman's console and use it as you would on any browser/client.

Using Postman's Console

Reminder! Use Postman snippets too!

Postman also has a selection of commonly-used test snippets to the right of the tests editor that will allow you to get up and running with both pre-request and post-request tests.

Running Tests in Collections and Folders

Remember you can add tests at different levels (collection, a folder, or a single request) within a collection. Postman lets you run an entire Collection of multiple folders and requests and also lets you run an entire Folder that contains multiple requests. When you run these, you will see the test results output by the test runner as follows:

Test Results at Collection Run

Conclusion

There are loads of possibilities to ensure that you are working with an integration that will provide a reliable user experience. You can try different authentication methods, HTTP Methods, HTTP requests and test them directly in Postman to make sure your API development and application runs smoothly. Don't forget to check out Postman's awesome Test Script example library to explore more possibilities! Happy Testing!

Thanks for reading!

Discussion (1)

Collapse
andrewbaisden profile image
Andrew Baisden

Postman is so good! Even though I have Thunder Client installed for VS Code I still use Postman more at the moment.