Belajar QA Automation Engineer - API Testing Automation
Episode 8 of 28

Belajar QA Automation Engineer - API Testing Automation

Menguasai API test automation: request frameworks, contract testing, mocking, dan membangun API test suite yang comprehensif

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 7 kita mempelajari POM untuk web testing, pada episode ini kita beralih ke layer yang sama pentingnya: API testing. API testing lebih cepat, lebih stabil, dan lebih murah dibanding E2E testing.

API Testing dengan Playwright

typescript
import { test, expect } from '@playwright/test';
 
test.describe('Users API', () => {
  test('GET /api/users returns list of users', async ({ request }) => {
    const response = await request.get('/api/users');
    expect(response.ok()).toBeTruthy();
 
    const users = await response.json();
    expect(Array.isArray(users)).toBeTruthy();
    expect(users.length).toBeGreaterThan(0);
  });
 
  test('POST /api/users creates user', async ({ request }) => {
    const response = await request.post('/api/users', {
      data: {
        name: 'John Doe',
        email: 'john@test.com'
      }
    });
 
    expect(response.status()).toBe(201);
    const user = await response.json();
    expect(user.name).toBe('John Doe');
    expect(user.email).toBe('john@test.com');
  });
 
  test('GET /api/users/:id returns user', async ({ request }) => {
    const response = await request.get('/api/users/1');
    expect(response.ok());
 
    const user = await response.json();
    expect(user).toHaveProperty('id', 1);
  });
});

Request Fixtures

typescript
// fixtures/api.ts
import { test as base } from '@playwright/test';
 
type ApiFixtures = {
  apiRequest: any;
};
 
export const test = base.extend<ApiFixtures>({
  apiRequest: async ({ request }, use) => {
    const apiRequest = {
      get: (url: string) => request.get(`http://localhost:3000${url}`),
      post: (url: string, data: any) =>
        request.post(`http://localhost:3000${url}`, { data }),
      put: (url: string, data: any) =>
        request.put(`http://localhost:3000${url}`, { data }),
      delete: (url: string) => request.delete(`http://localhost:3000${url}`),
    };
    await use(apiRequest);
  },
});

Contract Testing

typescript
// Contoh contract validation
test('user response matches contract', async ({ request }) => {
  const response = await request.get('/api/users/1');
  const user = await response.json();
 
  // Validate contract
  expect(user).toMatchObject({
    id: expect.any(Number),
    name: expect.any(String),
    email: expect.stringMatching(/@/),
    createdAt: expect.any(String),
  });
});

Mocking

typescript
// Mock API response
test('handle API error', async ({ page }) => {
  // Intercept API call
  await page.route('**/api/users', route => {
    route.fulfill({
      status: 500,
      body: JSON.stringify({ error: 'Internal Server Error' }),
    });
  });
 
  await page.goto('/users');
  await expect(page.locator('.error')).toContainText('Failed to load');
});
 
// Mock dengan delay
test('handle slow API', async ({ page }) => {
  await page.route('**/api/users', async route => {
    await new Promise(resolve => setTimeout(resolve, 3000));
    await route.continue();
  });
});

Note

API testing harus menjadi tulang punggung test strategy — lebih cepat dan stabil dari E2E. Gunakan E2E hanya untuk critical user flows.

Praktik: API Test Suite

typescript
test.describe('Products API', () => {
  test('GET /api/products', async ({ request }) => {
    const response = await request.get('/api/products');
    expect(response.ok());
    const products = await response.json();
    expect(products.length).toBeGreaterThan(0);
  });
 
  test('GET /api/products/:id', async ({ request }) => {
    const response = await request.get('/api/products/1');
    expect(response.ok());
    const product = await response.json();
    expect(product).toHaveProperty('name');
  });
 
  test('GET /api/products/:id - not found', async ({ request }) => {
    const response = await request.get('/api/products/99999');
    expect(response.status()).toBe(404);
  });
});

Penutup

  • Playwright API testing: request fixture untuk HTTP methods.
  • Contract testing: validate response shape dengan matchers.
  • Mocking: page.route() untuk intercept dan mock API responses.
  • Strategy: API testing sebagai tulang punggung, E2E untuk critical flows.

Di episode 9 selanjutnya kita akan membahas E2E testing strategy — best practices, test isolation, dan mengurangi flakiness. Sampai jumpa di episode 9!