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>
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"));
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"
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);
);
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);
);
Run with Newman
# Install Newman
npm install -g newman
# Run collection
newman run collection.json -e environment.json --reporters cli,junit
Playwright (TypeScript)
Playwright offers modern API testing with excellent TypeScript support.
Setup
npm init playwright@latest
npm install @faker-js/faker
// 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' ]]
);
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);
);
);
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
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
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
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.