Playwright P13: Quản lý nhiều môi trường test

⏱︎

Read time:

2–3 minutes
Playwright P13: Quản lý nhiều môi trường test

Cùng một bộ test có thể cần chạy trên Dev, QA hoặc Staging. Mỗi môi trường lại có cấu hình như base URL, API URL và tài khoản riêng, vậy cách nào tốt nhất để xử lý?

Cách 1: mỗi môi trường là một test project

Cách này đơn giản và phù hợp khi muốn khai báo các môi trường trực tiếp trong playwright.config.ts và có thể chạy một hoặc nhiều môi trường bằng --project.

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

export default defineConfig({
  testDir: './tests',
  projects: [
    {
      name: 'dev',
      use: { baseURL: 'https://dev.example.com' },
    },
    {
      name: 'qa',
      use: { baseURL: 'https://qa.example.com' },
    },
    {
      name: 'staging',
      use: { baseURL: 'https://staging.example.com' },
    },
  ],
});
npx playwright test --project=dev
npx playwright test --project=qa
npx playwright test --project=staging

# Chạy hai project trong cùng lệnh
npx playwright test --project=qa --project=staging

File test tương ứng:

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

test('mở trang đăng nhập', async ({ page }) => {
  await page.goto('/login');
  await expect(page.getByRole('heading')).toHaveText('Đăng nhập');
});

Với Playwright, page.goto("/login") tự ghép đường dẫn tương đối với baseURL của project đang chạy.

Ưu và nhược điểm của test projects

Ưu điểmHạn chế
Cấu hình rõ ràng, dùng sẵn --projectFile config dài khi có nhiều môi trường. Nhiều config giống nhau nhưng lặp đi lặp lại
Có thể chạy nhiều môi trường trong một lệnhProject còn thường dùng cho browser/device nên tên có thể phình to
Mỗi project có thể đặt timeout, retry, riêngSecret viết trực tiếp trong project -> Rủi ro security

Cách 2: tách file environment config

Cách này phù hợp khi mỗi lần chạy chỉ chọn một môi trường và mỗi môi trường có nhiều giá trị như web URL, API URL hoặc username. Các giá trị khác như timeout, retry… là không đổi.

Bước 1: tạo file config/environments.ts

export type EnvironmentName = 'dev' | 'qa' | 'staging';

type EnvironmentConfig = {
  webBaseUrl: string;
  apiBaseUrl: string;
  username: string;
};

const environments: Record<EnvironmentName, EnvironmentConfig> = {
  dev: {
    webBaseUrl: 'https://dev.example.com',
    apiBaseUrl: 'https://dev-api.example.com',
    username: 'dev-student',
  },
  qa: {
    webBaseUrl: 'https://qa.example.com',
    apiBaseUrl: 'https://qa-api.example.com',
    username: 'qa-student',
  },
  staging: {
    webBaseUrl: 'https://staging.example.com',
    apiBaseUrl: 'https://staging-api.example.com',
    username: 'staging-student',
  },
};

export function getEnvironment(): EnvironmentConfig {
  const name = (process.env.TEST_ENV ?? 'qa') as EnvironmentName;
  const config = environments[name];
  if (!config) throw new Error('Unknown TEST_ENV: ' + name);
  return config;
}

Bước 2: truyền config vào playwright.config.ts

import { defineConfig } from '@playwright/test';
import { getEnvironment } from './config/environments';

const environment = getEnvironment();

export default defineConfig({
  testDir: './tests',
  use: {
    baseURL: environment.webBaseUrl,
    extraHTTPHeaders: {
      'X-Test-Environment': process.env.TEST_ENV ?? 'qa',
    },
  },
  metadata: {
    environment: process.env.TEST_ENV ?? 'qa',
    apiBaseUrl: environment.apiBaseUrl,
  },
});

Bước 3: chọn môi trường khi chạy

# Cài cross-env để lệnh chạy giống nhau trên Windows/macOS/Linux
npm install -D cross-env

npx cross-env TEST_ENV=dev playwright test
npx cross-env TEST_ENV=qa playwright test
npx cross-env TEST_ENV=staging playwright test

Có thể đặt npm scripts cho dễ nhớ

{
  "scripts": {
    "test:dev": "cross-env TEST_ENV=dev playwright test",
    "test:qa": "cross-env TEST_ENV=qa playwright test",
    "test:staging": "cross-env TEST_ENV=staging playwright test"
  }
}

Không lưu secret trong source code

URL và username test có thể nằm trong config file ts. Password, token và API key nên lấy từ environment variables hoặc secret store của CI. Không được commit lên Git.