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' },
},
],
});*** Settings ***
Library SeleniumLibrary
*** Variables ***
${ENV} qa
${DEV_URL} https://dev.example.com
${QA_URL} https://qa.example.com
${STAGING_URL} https://staging.example.comnpx 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=stagingFile 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');
});*** Keywords ***
Lấy URL Theo Môi Trường
IF '${ENV}' == 'dev'
RETURN ${DEV_URL}
ELSE IF '${ENV}' == 'staging'
RETURN ${STAGING_URL}
END
RETURN ${QA_URL}
*** Test Cases ***
Mở Trang Đăng Nhập
${base_url}= Lấy URL Theo Môi Trường
Open Browser ${base_url}/login chrome
Page Should Contain Đăng nhập
[Teardown] Close BrowserVớ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ểm | Hạn chế |
|---|---|
Cấu hình rõ ràng, dùng sẵn --project | File 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ệnh | Project 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êng | Secret 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 testCó 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.



