Practical Example: Testing with Restful-Booker API
The Restful-Booker API is an excellent playground for learning API testing. Let's create some tests using this API.
Basic API Testing
First, let's explore the basic endpoints of the Restful-Booker API:
- Authentication: Obtain a token for subsequent authenticated requests
POST /auth
Content-Type: application/json
{
"username": "admin",
"password": "password123"
}
- Get Booking IDs: Retrieve a list of all booking IDs
GET /booking
- Get Specific Booking: Retrieve details for a specific booking
GET /booking/{id}
- Create Booking: Add a new booking
POST /booking
Content-Type: application/json
{
"firstname": "John",
"lastname": "Smith",
"totalprice": 111,
"depositpaid": true,
"bookingdates": {
"checkin": "2023-01-01",
"checkout": "2023-01-05"
},
"additionalneeds": "Breakfast"
}
- Update Booking: Modify an existing booking (requires authentication)
PUT /booking/{id}
Content-Type: application/json
Cookie: token={token-value}
{
"firstname": "John",
"lastname": "Doe",
"totalprice": 222,
"depositpaid": true,
"bookingdates": {
"checkin": "2023-02-01",
"checkout": "2023-02-05"
},
"additionalneeds": "Lunch"
}
- Delete Booking: Remove a booking (requires authentication)
DELETE /booking/{id}
Cookie: token={token-value}
Creating Tests in Postman
Let's create a collection in Postman to test the Restful-Booker API:
- Set up a Collection: Create a new collection named "Restful-Booker Tests"
- Create Environment Variables:
- Create a new environment called "Restful-Booker"
- Add variables:
baseUrl
: https://restful-booker.herokuapp.comusername
: adminpassword
: password123token
: (leave empty initially)bookingId
: (leave empty initially)- Authentication Request:
- Create a new request: POST {{baseUrl}}/auth
- Set body to raw JSON:
{
"username": "{{username}}",
"password": "{{password}}"
}
- Add Tests script:
pm.test("Status code is 200", function() {
pm.response.to.have.status(200);
});
pm.test("Response has token", function() {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property('token');
pm.environment.set("token", jsonData.token);
});
- Get Booking IDs Request:
- Create a new request: GET {{baseUrl}}/booking
- Add Tests script:
pm.test("Status code is 200", function() {
pm.response.to.have.status(200);
});
pm.test("Response is an array", function() {
var jsonData = pm.response.json();
pm.expect(jsonData).to.be.an('array');
if (jsonData.length > 0) {
pm.environment.set("bookingId", jsonData[^0].bookingid);
}
});
- Create Booking Request:
- Create a new request: POST {{baseUrl}}/booking
- Set body to raw JSON:
{
"firstname": "Test",
"lastname": "User",
"totalprice": 150,
"depositpaid": true,
"bookingdates": {
"checkin": "2025-05-01",
"checkout": "2025-05-05"
},
"additionalneeds": "Breakfast"
}
- Add Tests script:
pm.test("Status code is 200", function() {
pm.response.to.have.status(200);
});
pm.test("Booking created successfully", function() {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property('bookingid');
pm.environment.set("bookingId", jsonData.bookingid);
});
pm.test("Booking details are correct", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.booking.firstname).to.equal("Test");
pm.expect(jsonData.booking.lastname).to.equal("User");
pm.expect(jsonData.booking.totalprice).to.equal(150);
});
- Get Specific Booking Request:
- Create a new request: GET {{baseUrl}}/booking/{{bookingId}}
- Add Tests script:
pm.test("Status code is 200", function() {
pm.response.to.have.status(200);
});
pm.test("Booking exists", function() {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property('firstname');
pm.expect(jsonData).to.have.property('lastname');
});
- Update Booking Request:
- Create a new request: PUT {{baseUrl}}/booking/{{bookingId}}
- Add Headers:
- Cookie: token={{token}}
- Set body to raw JSON:
{
"firstname": "Updated",
"lastname": "User",
"totalprice": 200,
"depositpaid": true,
"bookingdates": {
"checkin": "2025-06-01",
"checkout": "2025-06-10"
},
"additionalneeds": "Dinner"
}
- Add Tests script:
pm.test("Status code is 200", function() {
pm.response.to.have.status(200);
});
pm.test("Booking was updated", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.firstname).to.equal("Updated");
pm.expect(jsonData.lastname).to.equal("User");
pm.expect(jsonData.totalprice).to.equal(200);
});
- Delete Booking Request:
- Create a new request: DELETE {{baseUrl}}/booking/{{bookingId}}
- Add Headers:
- Cookie: token={{token}}
- Add Tests script:
pm.test("Status code is 201", function() {
pm.response.to.have.status(201);
});
Working with Pre-request Scripts
Pre-request scripts in Postman execute before a request is sent, allowing you to set up the necessary conditions for your test. Let's enhance our collection with pre-request scripts:
- Authentication Request Pre-request Script:
// Generate a timestamp for logging
pm.variables.set("timestamp", new Date().toISOString());
console.log("Starting authentication at " + pm.variables.get("timestamp"));
- Create Booking Pre-request Script:
// Generate dynamic test data
const firstName = "Test" + Math.floor(Math.random() * 1000);
const lastName = "User" + Math.floor(Math.random() * 1000);
const price = Math.floor(Math.random() * 500) + 100;
// Store as variables for use in the request and tests
pm.variables.set("firstName", firstName);
pm.variables.set("lastName", lastName);
pm.variables.set("price", price);
// Update request body with dynamic data
const requestBody = {
"firstname": firstName,
"lastname": lastName,
"totalprice": price,
"depositpaid": true,
"bookingdates": {
"checkin": "2025-05-01",
"checkout": "2025-05-05"
},
"additionalneeds": "Breakfast"
};
pm.variables.set("requestBody", JSON.stringify(requestBody));
Then update the request body to use the variable:
{{requestBody}}
And update the corresponding test:
pm.test("Booking details are correct", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.booking.firstname).to.equal(pm.variables.get("firstName"));
pm.expect(jsonData.booking.lastname).to.equal(pm.variables.get("lastName"));
pm.expect(jsonData.booking.totalprice).to.equal(parseInt(pm.variables.get("price")));
});
- Collection-Level Pre-request Script (applies to all requests):
// Set global timestamp for the entire test run
if (!pm.globals.has("testRunId")) {
pm.globals.set("testRunId", new Date().toISOString());
}
// Log request information
console.log(`Executing request: ${pm.info.requestName}`);
console.log(`Test run ID: ${pm.globals.get("testRunId")}`);
// Verify token exists for authenticated requests
if (pm.request.url.toString().includes("/booking/") &&
(pm.request.method === "PUT" || pm.request.method === "DELETE")) {
if (!pm.environment.get("token")) {
console.error("Authentication token is missing!");
}
}
Integrating with Allure Reporting
To make our API tests more manager-friendly, we can integrate Allure reporting. While Postman doesn't directly support Allure, we can export our Postman collection and run it with Newman, then generate Allure reports.
Here's how to set it up:
- Export your Postman Collection:
- In Postman, export your "Restful-Booker Tests" collection
- Export your environment as well
- Install Required Tools:
npm install -g newman newman-reporter-allure
- Run Tests with Newman and Generate Allure Report:
newman run Restful-Booker-Tests.postman_collection.json -e Restful-Booker.postman_environment.json -r allure
- Generate and Open the Allure Report:
allure generate --clean
allure open
The Allure report provides a comprehensive, management-friendly overview of your API tests, including:
- Test Overview: Pass/fail statistics and execution trends
- Categories: Grouping of test failures by type
- Suites: Hierarchical view of test suites and cases
- Graphs: Visual representation of test execution results
- Timeline: Chronological view of test execution
- Behaviors: Functional breakdown of test cases
- Environment: Details about the test environment
For Java-based API testing frameworks like REST Assured, Allure integration is even more straightforward. As mentioned in the documentation, you would:
- Add the Allure REST Assured integration to your project dependencies
- Ensure you have the appropriate Allure adapter for your test framework (JUnit 5, Cucumber-JVM, etc.)
- Run your tests with the Allure listener enabled
- Generate the report with the Allure command-line tool