Keep going in our studies using Postman, in this article, we will do an pratical example, how we write the tests when we receive an API specification, how create, run and use newman to execute them.
Understanding what is going to be tested
To have a good test coverage and assure the quality of an API, we won't be starting directly in Postman, first, we'll understand the APIs that will be tested and after that, start think in how automate it.
Here is an workflow to help us in this process:
Let's start understanding the API that we will be testing. For this tutorial we will use the same API from the previous tutorial, the free API of Books. Reading the swagger, we don't have any explicit rule for the use of this API, but, that doesn't mean that we won't be testing it. When creating the tests, I suggest you use an table like this:
Endpoint | Method | Test | Expected Result |
---|---|---|---|
/Books | GET | Search all books with success | Return a status code 200 |
The model of response body for all requests is:
{
"id": 0,
"title": "string",
"description": "string",
"pageCount": 0,
"excerpt": "string",
"publishDate": "2023-10-14T18:44:34.674Z"
}
Based on Response body, we can do different tests, like:
Endpoint | Method | Test | Expected Result |
---|---|---|---|
/Books | GET | Search all books with success | - Return a status code 200 - The body response contain all fields non empty - The pageCount value is an integer |
Using the same strategy to the other endpoints:
Endpoint | Method | Test | Expected Result |
---|---|---|---|
/Books | GET | Search all books with success | - Return a status code 200 - The body response contain all fields non empty - The pageCount value is an integer |
/Books/{id} | GET | Search a specific book with success | - Return a status code 200 - The body response contain all fields non empty - The pageCount value is an integer |
/Books/{id} | GET | Search a specific book with invalid id | - Return a status code 404 - The title of message error should be "Not Found" |
/Books | POST | Create a book with success | - Return a status code 200 - The body response contain all fields non empty - The pageCount value is an integer |
/Books | POST | Create a book without body request | - Return a status code 415 |
/Books | POST | Create a book with empty body request | - Return a status code 200 - The fields of body response are filled with default configuration |
/Books/{id} | PUT | Update an book with success | - Return a status code 200 - The body response contain all fields non empty - The pageCount value is an integer |
/Books/{id} | PUT | Update a book passing an inexistent ID | - Return a status code 404 |
/Books/{id} | PUT | Update a book passing invalid ID | - Return a status code 400 |
/Books/{id} | PUT | Update a book with empty body request | - Return a status code 200 |
/Books/{id} | DELETE | Delete a book with success | - Return a status code 200 |
/Books/{id} | DELETE | Delete a book with inexistent ID | - Return a status code 404 |
There's more tests that you can do related to validation of the body request and the parameters that we need to send, I recommend you try it out!
Writing our tests
The process to create our tests using Postman will be:
- We'll create the collection
- Generate our requests based on our tests
- Start to write the tests using JavaScript and the Snippets from Postman.
After creating our requests, let's start to write our tests. As we can see, for all our tests, we validate the status code. To do this, we'll write the following method on the Test tab of each request:
pm.test("Status code is 2XX", function () {
pm.response.to.have.status(2XX); // change the status to what is expected in the test
});
The following test that is common to most part of our tests, is validate if the response body isn't empty, to do this, first, we will transform our response body into json format, and validate if the fields of the response body are not null using the command not.eql(null)
:
pm.test("Validating if the body response isn't null", function () {
var response = pm.response.json();
pm.expect(response.id).not.eql(null);
pm.expect(response.title).not.eql(null);
pm.expect(response.description).not.eql(null);
pm.expect(response.pageCount).not.eql(null);
pm.expect(response.excerpt).not.eql(null);
pm.expect(response.publishDate).not.eql(null);
});
Other test that we can execute is validate the content of the response, let's validate if the pageCount in our responses are an integer value or not:
pm.test("Type of content of pageCount", function () {
var response = pm.response.json().pageCount; // get the value of the response body
pm.expect(Number.isInteger(response)).to.be.true;
});
Now that we know how our tests will be, let's implement them and run our collection:
You can check the details of the tests here
Using Schemas to validate body response
Postman allows you to validate the schema of a body response. First, let's create the schema of our API:
{
"id":{
"type": "number"
},
"title":{
"type": "string"
},
"description":{
"type": "string"
},
"pageCount":{
"type": "number"
},
"excerpt":{
"type": "string"
},
"publishDate":{
"type": "string"
},
"required": ["id", "title", "description", "pageCount", "excerpt", "publishDate"]
}
Now, we'll save this value in as a variable in our environment, I've created a new one called Tests:
Now lets update our tests, we will call this variable and use the value to validate our body using Tiny Validator
library:
var schema = pm.environment.get("apiSchema");
pm.test("Validating the body response schema and type of pageCount", function () {
var response = pm.response.json();
response.forEach(response, function(item){
pm.expect(tv4.validate(item, schema)).to.be.true;
pm.expect(tv4.validate(item.pageCount, {"type": "number"})).to.be.true;
});
});
This is an alternative to reduce our time when is needed to validate the schema of some API.
Using Newman to run our tests
At previous tutorial, we learned how execute our collections through Postman interface, now we will learn how to run them through command line, to do it, first, we need to install Newman.
Newman is a command-line Collection Runner for Postman. It enables you to run and test a Postman Collection directly from the command line. It's built with extensibility in mind so that you can integrate it with your continuous integration (CI) servers and build systems.
Setup
Newman is built on Node.js. To run Newman, make sure you have Node.js installed. Follow the steps to download Node for your CI's platform.
If you already have node installed, ensure you are using Node.js v4 or above:
node -v
Install Newman from npm globally on your system, which allows you to run it from anywhere:
npm install -g newman
Executing the tests
To run your tests using Newman, first, export the collection and our environment file:
To do this, click at the collection and click on Export, the process is the same for the environment. After export, go to the folder of your collection command line and run the command:
newman run apiBooks-final.json -e test.postman_environment.json
You will receive all the results of the tests inside of this collection:
And we can see:
- The name of the tests
- The execution duration
- Average response time
- Which test pass and which failed
Generating reports
To help us to have a better view of our tests, is possible to generate a HTML file with the results of our run, we'll use the HTML reporter library. To install it use:
npm install -g newman-reporter-html
Now, when executing our tests we need to inform that we want to have the results at a html file:
newman run apiBooks-final.json -e test.postman_environment.json -r html
Newman will generate a folder with the report file, and the report will be shown like this:
You can generate other types of reports, I recommend take a look at newman package to select which one will fit your need.
Conclusion
This article is a tutorial of how you can start to write your tests for an API, how automate this using Postman and how you can use Newman to run your tests through command line and generate HTML reports.
You can access the collection used in this examples here.
I hope this content will be useful for you.
If you have any questions, feel free to reach out to me!
Bisous, à la semaine prochaine 💅🏼