Beginner's Guide in Testing APIs
Tags: postman, javascript, testing, beginners
Published: 2022-06-02 18:57:09

Previously in [Beginner's Guide to Working with APIs](https://dev.to/ekqt/beginners-guide-to-working-with-apis-2k01) 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](https://learning.postman.com/docs/writing-scripts/test-scripts/) 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](https://nodejs.dev/). Therefore, you can run your script during 2 events in the flow:

1. Before an HTTP Request is sent, as a [pre-request script](https://learning.postman.com/docs/writing-scripts/pre-request-scripts/),
2. After an HTTP Response is received, as a [test-script](https://learning.postman.com/docs/writing-scripts/intro-to-scripts/#:~:text=received%2C%20as%20a-,test%20script,-under%20the%20Tests)

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](https://res.cloudinary.com/dmca9ldbv/image/upload/v1654195343/blog/beginners-guide-in-testing-apis/req-resp_roctgb.png)

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](https://dev.to/ekqt/beginners-guide-to-working-with-apis-2k01#:~:text=using%20our%20first-,Postman%20Collection,-.), which has been build based on the very popular [JSON Placeholder](https://jsonplaceholder.typicode.com/) 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:

```javascript
pm.test("Status code is 201", () => {
    const response = pm.response;
    pm.expect(response.code).to.eql(201);
});
```

### 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:

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

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](https://en.wikipedia.org/wiki/Test_assertion). Postman tests can use [Chai Assertion Library BDD](https://www.chaijs.com/api/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](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:

1. Information responses (`100` - `199`)
2. [Successful responses](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#successful_responses) (`200` - `299`)
3. Redirection messages (`300` - `399`)
4. [Client error responses](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses) (`400` - `499`)
5. [Server error responses](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#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](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201) 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:

```javascript
/****
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;
});
```

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](https://res.cloudinary.com/dmca9ldbv/image/upload/v1654195345/blog/beginners-guide-in-testing-apis/logs-in-console-v8_zdqlkx.jpg)

### 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](https://res.cloudinary.com/dmca9ldbv/image/upload/v1654195346/blog/beginners-guide-in-testing-apis/collection-tests-run-v9_tqsdjz.jpg)

## 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](https://learning.postman.com/docs/writing-scripts/script-references/test-examples/) to explore more possibilities! Happy Testing!

Thanks for reading!