Playwright P12: Test API với Playwright

⏱︎

Read time:

3–4 minutes
Playwright P12: Test API với Playwright

Bạn hoàn toàn có thể test API với Playwright. Playwright cung cấp APIRequestContext để gửi HTTP request trực tiếp từ test, thứ mà Selenium bó tay.

Ví dụ
Ví dụ dưới đây là 1 bài toán cơ bản trong API testing: Login với Username và Password để lấy token, sau đó dùng token đó để GET số lượng bài viết, hoặc POST tạo bài viết mới cho 1 hệ thống blog cá nhân.

Cấu hình header dùng chung

Chúng ta có thể cấu hình những thành phần không đổi cho 1 API header tại file config như sau, cách thành phần này sẽ được tự động append vào header về sau:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    extraHTTPHeaders: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
  },
});

Bước 1: POST đăng nhập thông qua API

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

test('đăng nhập và lấy token', async ({ request }) => {
  const response = await request.post('/api/users/login', {
    data: {
      user: {
// 2 biến này có sẵn trong môi trường
        email: process.env.API_EMAIL,
        password: process.env.API_PASSWORD,
      },
    },
  });

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

  const body = await response.json();
  expect(body.user.token).toBeTruthy();
  expect(body.user.email).toBe(process.env.API_EMAIL);
});

response.status() trả status code cụ thể; response.ok() đúng với response từ 200 đến 299. Trong bài test thực tế nên kiểm tra status code chính xác theo API documentation, không chỉ kiểm tra chung chung 2xx.

Tạo 1 hàm helper đăng nhập dùng lại

Muốn tạo bài viết mới, hay get list bài viết thì đều cần token là tiền điều kiện. Vì vậy hãy tạo 1 hàm truyền tên đăng nhập và mật khẩu vào, sau đó trả ra token để có thể sử dụng:

async function loginAndGetToken(request): Promise<string> {
  const response = await request.post('/api/users/login', {
    data: {
      user: {
        email: process.env.API_EMAIL,
        password: process.env.API_PASSWORD,
      },
    },
  });

  expect(response.status()).toBe(200);
  return (await response.json()).user.token;
}

Bước 2: GET danh sách bài viết với header Token

test('GET danh sách bài viết', async ({ request }) => {
  const token = await loginAndGetToken(request);

  const response = await request.get('/api/articles', {
    headers: {
      Authorization: 'Bearer ' + token,
    },
    params: { limit: 10, offset: 0 },
  });

  expect(response.status()).toBe(200);
  const body = await response.json();
  expect(Array.isArray(body.articles)).toBeTruthy();
  expect(body.articlesCount).toBeGreaterThanOrEqual(0);
});

Bước 3: POST tạo bài viết và verify response

test('POST tạo bài viết', async ({ request }) => {
  const token = await loginAndGetToken(request);
  const title = 'Bài viết mới ' + Date.now();

  const response = await request.post('/api/articles', {
    headers: {
      Authorization: 'Bearer ' + token,
    },
    data: {
      article: {
        title: title ,
        description: 'Bài viết được tạo bởi automated test',
        body: 'Nội dung dùng cho bài học Playwright API testing.',
        tagList: ['playwright', 'api-testing'],
      },
    },
  });

  expect(response.status()).toBe(201);
  const body = await response.json();
  expect(body.article.title).toBe(uniqueTitle);
  expect(body.article.slug).toBeTruthy();
  expect(body.article.tagList).toContain('playwright');
});

Nên kiểm tra những gì trong API response?

NhómVí dụ
StatusGET thành công là 200; tạo thành công là 201
Schema cơ bảnField bắt buộc tồn tại và đúng kiểu
Business dataCác giá trị trả về là chính xác so với những giá trị gửi lên
Negative caseToken sai trả 401, body sai trả 422… không được trả 500