DEV Community

Cover image for API Testing using Postman
Lloyd Marcelino
Lloyd Marcelino

Posted on

API Testing using Postman

In the dynamic world of API testing, versatility is key. With Postman, a leading API testing tool, there's no one-size-fits-all approach to test codes. The significance of each test hinges on the unique demands and context of your API. But fear not! Whether you're a seasoned developer or just starting out, understanding the landscape of API testing is crucial. In this insightful guide, we'll delve into the diverse and vital types of tests. Get ready to enhance your API testing skills and bring precision and efficiency to your projects!

Types of Test

There isn't a single "most important" test code, as the importance of a test depends on the specific requirements and context of the API you are testing. However, there are several common and crucial types of tests that are often used in API testing with Postman:

  • Status Code Verification: Ensuring that the API returns the expected HTTP status code. For example, a 200 OK for successful requests, 404 Not Found for invalid endpoints, or 500 Internal Server Error for server issues.
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

Enter fullscreen mode Exit fullscreen mode

  • Response Time Validation: Checking that the API responds within an acceptable time frame. This is crucial for performance testing.
pm.test("Response time is less than 500ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(500);
});

Enter fullscreen mode Exit fullscreen mode

  • Data Validation: Ensuring that the response body contains the correct data. This could involve checking the structure of the response JSON or XML, and verifying that the values are as expected.
pm.test("Response body has correct data", function () {
    var responseJson = pm.response.json();
    pm.expect(responseJson.name).to.eql("John Doe");
    pm.expect(responseJson.id).to.eql(123);
});

Enter fullscreen mode Exit fullscreen mode

  • Header Checks: Verifying that the HTTP headers in the response are correct. This can include checks for content type, security headers, etc.
pm.test("Content-Type header is present and application/json", function () {
    pm.response.to.have.header("Content-Type", "application/json");
});

Enter fullscreen mode Exit fullscreen mode

  • Authentication and Authorization Tests: Ensuring that requests are properly authenticated and that users have the correct authorization level for different requests.
pm.test("Response should be unauthorized", function () {
    pm.response.to.have.status(401);
});

Enter fullscreen mode Exit fullscreen mode

  • Error Handling Tests: Verifying that the API handles errors gracefully and returns appropriate error messages and codes.
pm.test("Error message is as expected", function () {
    var responseJson = pm.response.json();
    pm.expect(responseJson.error).to.eql("Invalid request parameters");
});

Enter fullscreen mode Exit fullscreen mode

  • Business Logic Verification: Testing the actual business logic that the API implements, to ensure it meets the specified requirements.
pm.test("Discount is applied correctly", function () {
    var responseJson = pm.response.json();
    pm.expect(responseJson.total).to.eql(responseJson.subtotal - responseJson.discount);
});

Enter fullscreen mode Exit fullscreen mode

  • Schema Validation: Ensuring that the response follows a defined schema or structure, which is particularly important for RESTful APIs.
const schema = {
    "type": "object",
    "required": ["name", "id"],
    "properties": {
        "name": {"type": "string"},
        "id": {"type": "number"}
    }
};

pm.test("Schema is valid", function() {
    pm.response.to.have.jsonSchema(schema);
});

Enter fullscreen mode Exit fullscreen mode

  • Integration Tests: Checking how the API interacts with other services and databases.
pm.test("User profile data matches with database", function () {
    // Here you'd typically use pm.sendRequest to query another API or database
    // For demonstration, assuming a static check
    var responseJson = pm.response.json();
    pm.expect(responseJson.username).to.eql("user_from_db");
});

Enter fullscreen mode Exit fullscreen mode

  • Security Tests: Identifying vulnerabilities in the API, like SQL injection, Cross-Site Scripting (XSS), and other security threats.
pm.test("No SQL Injection vulnerability", function () {
    // This would ideally involve sending a potentially malicious SQL code in the request and checking the response
    pm.response.to.not.have.status(500); // Simple check for server error
    pm.response.to.not.have.body("SQL"); // Ensure response does not contain SQL error messages
});

Enter fullscreen mode Exit fullscreen mode

GET Test

Let's consider a more complex and tailored test for a hypothetical GET API request. This API, for example, could be for retrieving user profile information. The test will cover various aspects, including status code verification, response time, data validation, schema validation, and some custom logic related to the data returned.

Hypothetical API Details:

  • Endpoint: /api/users/{userId}
  • Method: GET
  • Response Structure:
{
    "userId": "string",
    "name": "string",
    "email": "string",
    "roles": ["string"],
    "isActive": "boolean",
    "lastLogin": "string" // Date in ISO format
}

Enter fullscreen mode Exit fullscreen mode

Sample Test Code in Postman:

// Test for Status Code and Response Time
pm.test("Status code is 200 and response time is acceptable", function () {
    pm.response.to.have.status(200);
    pm.expect(pm.response.responseTime).to.be.below(1000); // assuming 1000ms as the threshold
});

// Data Validation with Multiple Checks
pm.test("Response body has correct data structure", function () {
    let responseJson = pm.response.json();
    pm.expect(responseJson).to.have.keys("userId", "name", "email", "roles", "isActive", "lastLogin");
    pm.expect(responseJson.userId).to.be.a('string');
    pm.expect(responseJson.name).to.be.a('string');
    pm.expect(responseJson.email).to.match(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/); // Email format validation
    pm.expect(responseJson.roles).to.be.an('array');
    pm.expect(responseJson.isActive).to.be.a('boolean');
    pm.expect(new Date(responseJson.lastLogin)).to.be.a('date');
});

// Schema Validation (assuming a predefined schema variable)
const userProfileSchema = {
    "type": "object",
    "required": ["userId", "name", "email", "roles", "isActive", "lastLogin"],
    "properties": {
        "userId": {"type": "string"},
        "name": {"type": "string"},
        "email": {"type": "string", "format": "email"},
        "roles": {
            "type": "array",
            "items": {"type": "string"}
        },
        "isActive": {"type": "boolean"},
        "lastLogin": {"type": "string", "format": "date-time"}
    }
};

pm.test("Schema is valid", function() {
    pm.response.to.have.jsonSchema(userProfileSchema);
});

// Custom Logic Check
pm.test("User is active and has logged in within the last month", function () {
    let responseJson = pm.response.json();
    pm.expect(responseJson.isActive).to.be.true;
    let lastLoginDate = new Date(responseJson.lastLogin);
    let aMonthAgo = new Date();
    aMonthAgo.setMonth(aMonthAgo.getMonth() - 1);
    pm.expect(lastLoginDate).to.be.above(aMonthAgo);
});

Enter fullscreen mode Exit fullscreen mode

In this example, we have created a more comprehensive set of tests that not only check the basic aspects like status code and response time but also validate the data structure, ensure the response matches a predefined schema, and include a custom logic check to validate business rules (e.g., the user's active status and recent login).

PUT Test

Let's consider a PUT API request that updates user details. This type of request often requires careful testing to ensure data integrity and adherence to business rules.

Hypothetical API Details:

  • Endpoint: /api/users/{userId}
  • Method: PUT
  • Request Body:
{
  "name": "string",
  "email": "string",
  "isActive": "boolean"
}

Enter fullscreen mode Exit fullscreen mode
  • Expected Response: Status code 200 for successful update, with a JSON body containing the updated user details.

Sample Test Code in Postman:

// Variables for Request Data
const requestData = pm.request.body.toJSON();

// Test for Status Code
pm.test("Status code is 200 for successful update", function () {
    pm.response.to.have.status(200);
});

// Response Time Validation
pm.test("Response time is within acceptable limits", function () {
    pm.expect(pm.response.responseTime).to.be.below(2000); // 2000ms as a threshold
});

// Data Validation
pm.test("Response body matches updated data", function () {
    let responseJson = pm.response.json();
    pm.expect(responseJson.name).to.eql(requestData.name);
    pm.expect(responseJson.email).to.eql(requestData.email);
    pm.expect(responseJson.isActive).to.eql(requestData.isActive);
});

// Email Format Check
pm.test("Email format is valid", function () {
    let responseJson = pm.response.json();
    pm.expect(responseJson.email).to.match(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/); // Simple regex for email validation
});

// Check for Required Fields in Response
pm.test("Response has all required fields", function () {
    let responseJson = pm.response.json();
    pm.expect(responseJson).to.have.all.keys("userId", "name", "email", "isActive");
});

// Custom Business Rule Check (Example: isActive should not be true if user's email is not verified)
pm.test("Active status should not be true for unverified email", function () {
    let responseJson = pm.response.json();
    if (responseJson.isActive) {
        // Assuming there's a field in response that indicates email verification status
        pm.expect(responseJson.isEmailVerified).to.be.true;
    }
});

// Additional Security Check (e.g., Checking for unexpected modifications)
pm.test("Response should not contain sensitive data", function () {
    let responseJson = pm.response.json();
    pm.expect(responseJson).to.not.have.keys("password", "securityQuestionAnswers");
});

Enter fullscreen mode Exit fullscreen mode

In this example, the tests are tailored to verify not only the basic functionality of the PUT request (like status code and response structure) but also to ensure that the update adheres to business rules and security standards. The tests check if the response data matches the update request, validate the email format, ensure no sensitive data is exposed, and include a custom check related to the business logic (like the user's active status in relation to their email verification status).

Remember, the specifics of your tests will vary based on the exact nature of your API, its business logic, security considerations, and other factors unique to your application.

Top comments (0)