Q33 of 42 · Playwright

Compare Playwright's APIRequestContext for backend testing vs a separate API test framework.

PlaywrightSeniorplaywrightapi-testingrequest-contexttool-comparisonsenior

Short answer

Short answer: `APIRequestContext` (`request` fixture or `page.request`) makes HTTP calls with cookie/storage sharing with browser tests — ideal for setup, teardown, and hybrid API+UI tests. A dedicated API framework (Postman, REST Assured, Hurl, supertest) is better for pure API contract testing because of richer schema/assertion tooling.

Detail

Playwright ships APIRequestContext — the request fixture in tests. It's a fully-featured HTTP client that shares cookies and auth state with the page:

test('hybrid API + UI test', async ({ page, request }) => {
  // API setup — fast and reliable
  const order = await request.post('/api/orders', {
    data: { items: [...], total: 100 },
  });
  expect(order.status()).toBe(201);
  const { id } = await order.json();

  // UI verification
  await page.goto(`/orders/${id}`);
  await expect(page.getByTestId('order-status')).toHaveText('Pending');
});

Strengths:

  • Cookie sharing with the browser context — log in via UI, hit APIs as the same user.
  • Same fixture / runner / report as your E2E. No tool sprawl.
  • TypeScript types match the rest of your test code.
  • Trace integration — API calls show up in the Playwright trace viewer.

Weaknesses (vs a dedicated API framework):

  • Schema validation isn't built in. You'd add Ajv or Zod yourself. REST Assured / Postman ship it.
  • Contract testing (Pact) integrates better outside Playwright.
  • Performance / load testing — Playwright isn't optimised for hammering endpoints; k6 or JMeter is.
  • Visualisation / collections — Postman's collections + Newman runner is a richer authoring environment for non-engineers.

The pragmatic split:

  • Use APIRequestContext for: test setup/teardown, hybrid scenarios, smoke checks against APIs.
  • Use a dedicated API framework for: pure API contract suites, schema-strict regression, performance, broader stakeholder authoring.

A common architecture: Playwright owns the E2E + hybrid layer; a separate api-tests/ package using something like supertest + zod + vitest covers the deep API regression. Both contribute to release confidence.

Watch-out for hybrid tests: don't try to test the API contract via Playwright. expect(response.status()).toBe(201) is fine, but full schema validation, error case enumeration, and contract pinning belong in dedicated API tests where the assertion vocabulary is richer.

// EXAMPLE

hybrid.spec.ts

import { test, expect } from '@playwright/test';

test('checkout — API setup, UI verification', async ({ page, request }) => {
  // 1. Auth (shared cookie state)
  await request.post('/api/login', {
    data: { email: 'alice@x.com', password: 'pwd' },
  });

  // 2. Seed order via API (fast, deterministic)
  const create = await request.post('/api/orders', {
    data: {
      items: [{ sku: 'p1', qty: 2 }],
      shippingAddress: { country: 'GB', postcode: 'SW1A 1AA' },
    },
  });
  expect(create.status()).toBe(201);
  const { id } = await create.json();

  // 3. UI assertion
  await page.goto(`/orders/${id}`);
  await expect(page.getByTestId('status')).toHaveText('Pending');
});

// WHAT INTERVIEWERS LOOK FOR

Knowing the strengths (cookie sharing, hybrid tests) and weaknesses (no built-in schema, weaker contract tooling), and the pragmatic split between hybrid and pure API tests.

// COMMON PITFALL

Using `APIRequestContext` for full API contract testing without schema validation — you re-invent half a framework.