DEV Community

API Testing Frameworks Comparison: REST Assured vs Postman vs Playwright

API testing is crucial for ensuring your services work correctly. In this article, we'll compare three popular API testing frameworks with real-world examples.

Table of Contents

Overview

We'll test a simple Product API with these endpoints:

  • GET /products/{id} - Get product by ID
  • POST /products - Create new product
  • PUT /products/{id} - Update product

REST Assured (Java)

REST Assured uses a fluent API with Given-When-Then syntax, perfect for Java developers.

Setup

<!-- pom.xml -->
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Basic Test Example

import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
import org.junit.jupiter.api.Test;

public class ProductApiTest {

    @Test
    public void testGetProduct() {
        given()
            .baseUri("https://api.example.com")
            .header("Authorization", "Bearer token123")
        .when()
            .get("/products/1")
        .then()
            .statusCode(200)
            .contentType("application/json")
            .body("id", equalTo(1))
            .body("name", notNullValue())
            .body("price", greaterThan(0.0f));
    }

    @Test
    public void testCreateProduct() {
        String productJson = """
            {
                "name": "Laptop",
                "price": 999.99,
                "category": "Electronics"
            }
            """;

        given()
            .baseUri("https://api.example.com")
            .header("Authorization", "Bearer token123")
            .contentType("application/json")
            .body(productJson)
        .when()
            .post("/products")
        .then()
            .statusCode(201)
            .body("id", notNullValue())
            .body("name", equalTo("Laptop"));
    }
}
Enter fullscreen mode Exit fullscreen mode

Postman/Newman (JavaScript)

Postman provides a visual interface, while Newman runs collections from command line.

Collection Setup

Create a Postman collection with environment variables:

{
  "baseUrl": "https://api.example.com",
  "authToken": "Bearer token123"
}
Enter fullscreen mode Exit fullscreen mode

Pre-request Script

// Get auth token if not exists
if (!pm.environment.get("authToken")) {
    pm.sendRequest({
        url: pm.environment.get("authUrl") + "/login",
        method: 'POST',
        header: { 'Content-Type': 'application/json' },
        body: {
            mode: 'raw',
            raw: JSON.stringify({
                username: "testuser",
                password: "testpass"
            })
        }
    }, (err, response) => {
        if (!err) {
            const token = response.json().token;
            pm.environment.set("authToken", "Bearer " + token);
        }
    });
}
Enter fullscreen mode Exit fullscreen mode

Test Script

// Test GET /products/1
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

pm.test("Response has required fields", function () {
    const product = pm.response.json();
    pm.expect(product).to.have.property('id');
    pm.expect(product).to.have.property('name');
    pm.expect(product).to.have.property('price');
    pm.expect(product.price).to.be.above(0);
});

pm.test("Response time is acceptable", function () {
    pm.expect(pm.response.responseTime).to.be.below(2000);
});

// Save product ID for next requests
pm.test("Save product data", function () {
    const product = pm.response.json();
    pm.environment.set("productId", product.id);
});
Enter fullscreen mode Exit fullscreen mode

Run with Newman

# Install Newman
npm install -g newman

# Run collection
newman run collection.json -e environment.json --reporters cli,junit
Enter fullscreen mode Exit fullscreen mode

Playwright (TypeScript)

Playwright offers modern API testing with excellent TypeScript support.

Setup

npm init playwright@latest
npm install @faker-js/faker
Enter fullscreen mode Exit fullscreen mode
// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    baseURL: 'https://api.example.com',
    extraHTTPHeaders: {
      'Authorization': 'Bearer token123'
    }
  },
  reporter: [['html'], ['junit', { outputFile: 'results.xml' }]]
});
Enter fullscreen mode Exit fullscreen mode

Test Example

// tests/product-api.spec.ts
import { test, expect } from '@playwright/test';
import { faker } from '@faker-js/faker';

test.describe('Product API Tests', () => {

  test('should get product by ID', async ({ request }) => {
    const response = await request.get('/products/1');

    expect(response.ok()).toBeTruthy();
    expect(response.status()).toBe(200);

    const product = await response.json();
    expect(product).toHaveProperty('id', 1);
    expect(product).toHaveProperty('name');
    expect(product).toHaveProperty('price');
    expect(product.price).toBeGreaterThan(0);
  });

  test('should create new product', async ({ request }) => {
    const newProduct = {
      name: faker.commerce.productName(),
      price: parseFloat(faker.commerce.price()),
      category: 'Electronics'
    };

    const response = await request.post('/products', {
      data: newProduct
    });

    expect(response.status()).toBe(201);

    const createdProduct = await response.json();
    expect(createdProduct.name).toBe(newProduct.name);
    expect(createdProduct.price).toBe(newProduct.price);
  });

  test('should handle not found error', async ({ request }) => {
    const response = await request.get('/products/99999');

    expect(response.status()).toBe(404);

    const error = await response.json();
    expect(error).toHaveProperty('message');
  });

  test('should validate response time', async ({ request }) => {
    const startTime = Date.now();
    await request.get('/products/1');
    const responseTime = Date.now() - startTime;

    expect(responseTime).toBeLessThan(2000);
  });
});
Enter fullscreen mode Exit fullscreen mode

Run Tests

# Run all tests
npx playwright test

# Run specific test file
npx playwright test tests/product-api.spec.ts

# Run with UI mode
npx playwright test --ui
Enter fullscreen mode Exit fullscreen mode

Comparison Table

Feature REST Assured Postman/Newman Playwright
Language Java JavaScript TypeScript/JS
Learning Curve Medium Easy Medium
Setup Complexity Medium Easy Easy
CI/CD Integration Excellent Good Excellent
Reporting Good Excellent Excellent
Parallel Execution Yes Limited Yes
Data Generation Manual Manual Built-in (Faker)
Debugging IDE GUI + Console VS Code + UI Mode

When to Use Each

Choose REST Assured if:

  • Your team uses Java/JVM languages
  • You need complex test logic and assertions
  • You want strong IDE integration
  • You're testing Java microservices

Choose Postman/Newman if:

  • You need visual test creation
  • Your team prefers GUI tools
  • You want easy collaboration and sharing
  • You need detailed test documentation

Choose Playwright if:

  • You want modern tooling with TypeScript
  • You need both API and E2E testing
  • You want excellent debugging capabilities
  • You value fast execution and parallel testing

Example Repository Structure

api-testing-comparison/
├── rest-assured/
│   ├── pom.xml
│   └── src/test/java/ProductApiTest.java
├── postman/
│   ├── collection.json
│   ├── environment.json
│   └── package.json
├── playwright/
│   ├── playwright.config.ts
│   ├── package.json
│   └── tests/product-api.spec.ts
└── README.md
Enter fullscreen mode Exit fullscreen mode

GitHub Actions CI Example

# .github/workflows/api-tests.yml
name: API Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        framework: [rest-assured, newman, playwright]

    steps:
    - uses: actions/checkout@v3

    - name: Setup Java (REST Assured)
      if: matrix.framework == 'rest-assured'
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'

    - name: Setup Node.js (Newman/Playwright)
      if: matrix.framework != 'rest-assured'
      uses: actions/setup-node@v3
      with:
        node-version: '18'

    - name: Run REST Assured Tests
      if: matrix.framework == 'rest-assured'
      run: |
        cd rest-assured
        mvn test

    - name: Run Newman Tests
      if: matrix.framework == 'newman'
      run: |
        cd postman
        npm install -g newman
        newman run collection.json -e environment.json

    - name: Run Playwright Tests
      if: matrix.framework == 'playwright'
      run: |
        cd playwright
        npm ci
        npx playwright install
        npx playwright test
Enter fullscreen mode Exit fullscreen mode

Conclusion

Each framework has its strengths:

  • REST Assured excels in Java environments with powerful assertions
  • Postman/Newman provides the best user experience for manual and automated testing
  • Playwright offers modern tooling with excellent TypeScript support

Choose based on your team's skills, existing tech stack, and testing requirements. You can also use multiple frameworks for different types of testing in the same project.

Top comments (1)

Collapse
 
luc_36689a31b94d68d29f9e9 profile image
luc

Interesting comparison! While REST Assured, Postman, and Playwright all have their strengths, I think it's crucial to consider the overall API lifecycle, not just the testing phase.
That's why I've been increasingly using Apidog for a lot of my new projects. There's API generation that test and make a test!
Apidog provides the security while being collaborative. You can easily add an API framework, and easily test code!

I recommend to any testers.