Playwright 第13章:CI/CD 集成
将 Playwright 测试集成到 CI/CD 流水线中可以实现自动化测试的持续运行。本章介绍 GitHub Actions 配置、Docker 运行、测试分片以及报告上传等 CI/CD 最佳实践。
GitHub Actions 配置
基础工作流配置
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * *' # 每天 6:00 运行
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
多浏览器并行测试
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
browser: [chromium, firefox, webkit]
shardIndex: [1, 2, 3]
shardTotal: [3]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run tests
run: |
npx playwright test \
--project=${{ matrix.browser }} \
--shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
env:
CI: true
- name: Upload report
uses: actions/upload-artifact@v4
if: always()
with:
name: report-${{ matrix.browser }}-shard-${{ matrix.shardIndex }}
path: playwright-report/
retention-days: 7
注意:GitHub Actions 中的 ${{ }} 是 GitHub Actions 的表达式语法,在 YAML 文件中按原样编写即可。但如果在 TypeScript 模板字符串中嵌入 YAML 示例,需要确保不冲突。
合并分片报告
jobs:
merge-reports:
if: always()
needs: [test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Download all artifacts
uses: actions/download-artifact@v4
- name: Install dependencies
run: npm ci
- name: Merge reports
run: npx playwright merge-reports --reporter html ./report-*/
- name: Upload merged report
uses: actions/upload-artifact@v4
with:
name: merged-report
path: playwright-report/
retention-days: 30
报告部署到 GitHub Pages
- name: Deploy report to GitHub Pages
if: always()
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./playwright-report
destination_dir: test-reports
keep_files: true
Docker 运行
Playwright Docker 镜像
Playwright 官方提供预装了浏览器和系统依赖的 Docker 镜像:
# Dockerfile
FROM mcr.microsoft.com/playwright:v1.45.0-focal
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
RUN npm ci
# 复制源码
COPY . .
# 运行测试
CMD ["npx", "playwright", "test"]
Docker Compose 配置
# docker-compose.yml
version: '3.8'
services:
playwright:
build: .
environment:
- CI=true
- BASE_URL=http://webapp:3000
volumes:
- ./playwright-report:/app/playwright-report
- ./test-results:/app/test-results
depends_on:
- webapp
webapp:
build: ./webapp
ports:
- "3000:3000"
environment:
- NODE_ENV=test
在 Docker 中运行测试
# 构建镜像
docker build -t playwright-tests .
# 运行测试
docker run --rm \
-v $(pwd)/playwright-report:/app/playwright-report \
-v $(pwd)/test-results:/app/test-results \
playwright-tests
# 使用 Docker Compose
docker compose up --abort-on-container-exit
分片测试(Shard)
分片工作原理
分片将测试集划分为多个片段,每个片段在独立的 worker 上并行执行:
# 将测试分为 4 片,同时在 4 个 runner 上执行
npx playwright test --shard=1/4
npx playwright test --shard=2/4
npx playwright test --shard=3/4
npx playwright test --shard=4/4
# 合并结果
npx playwright merge-reports --reporter html ./shard-results/
分片配置
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
// 开启分片报告合并
reporter: process.env.CI ? [
['blob', { outputDir: './blob-report' }],
['html', { outputFolder: './playwright-report' }],
] : [
['html'],
['list'],
],
});
CI 中的分片策略
jobs:
test:
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- name: Run tests
run: npx playwright test --shard=${{ matrix.shard }}/4
report:
needs: [test]
steps:
- name: Merge blob reports
run: npx playwright merge-reports --reporter html ./blob-report/
无头模式配置
不同环境下的无头配置
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// CI 中使用无头模式
headless: process.env.CI ? true : false,
// Linux 环境需要额外参数
launchOptions: process.platform === 'linux' ? {
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-gpu',
],
} : {},
},
});
视频和截图记录
export default defineConfig({
use: {
// CI 中记录失败截图
screenshot: process.env.CI ? 'only-on-failure' : 'off',
// CI 中记录失败视频
video: process.env.CI ? 'retain-on-failure' : 'off',
// CI 中记录 Trace
trace: process.env.CI ? 'on-first-retry' : 'off',
},
});
性能优化
CI 加速策略
// playwright.config.ts
export default defineConfig({
// 仅在 CI 中使用重试
retries: process.env.CI ? 2 : 0,
// CI 中限制并行数
workers: process.env.CI ? 4 : undefined,
// 全局超时
timeout: process.env.CI ? 60000 : 30000,
});
缓存策略
- name: Cache Playwright browsers
uses: actions/cache@v3
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-playwright-
其他 CI 平台配置
GitLab CI
# .gitlab-ci.yml
stages:
- test
playwright:
stage: test
image: mcr.microsoft.com/playwright:v1.45.0-focal
script:
- npm ci
- npx playwright test
artifacts:
when: always
paths:
- playwright-report/
expire_in: 30 days
Jenkins Pipeline
// Jenkinsfile
pipeline {
agent {
docker { image 'mcr.microsoft.com/playwright:v1.45.0-focal' }
}
stages {
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Test') {
steps {
sh 'npx playwright test'
}
post {
always {
archiveArtifacts artifacts: 'playwright-report/**', allowEmptyArchive: true
}
}
}
}
}
总结
CI/CD 集成是 Playwright 测试自动化的关键环节。GitHub Actions 提供最便捷的集成方式,Docker 确保环境一致性,分片策略实现高效并行执行。建议在 CI 中开启视频和截图记录便于问题排查,合理设置重试策略平衡稳定性和耗时。报告上传和部署为团队提供可视化的测试结果,是持续改进测试质量的重要依据。