English | 中文
强大的 Playwright 测试编排器、执行器和报告器,提供 CLI 命令行工具和 Web Dashboard 可视化界面,帮助团队更高效地管理和分析 E2E 测试。
@slow, @flaky, @skip 等测试注解yuantest-playwright 提供完整的测试生命周期管理,无需组合多个工具:
| 功能模块 | 说明 |
|---|---|
| Orchestrator | 智能测试分片、负载均衡、基于历史时间的优化分配 |
| Executor | 通过 Playwright CLI 执行,无内部 API 依赖,升级兼容性强 |
| RealtimeReporter | WebSocket 实时推送测试进度 |
| DashboardServer | 完整的 Web UI + REST API |
| FlakyTestManager | 自动检测、隔离、统计不稳定测试 |
| ArtifactManager | 统一管理截图、视频、Trace 文件 |
这是项目的核心差异化价值,市场上稀缺的能力:
// 自动记录测试历史,计算失败率
existing.failureRate = failures / totalRuns;
// 支持一键隔离
yuantest flaky --quarantine <test-id>
threshold)// ShardOptimizer - 基于历史执行时间优化分片
const optimizedAssignments = await optimizer.optimize(tests, shards);
// 通过 Playwright CLI 执行,而非内部 API
spawn('npx', ['playwright', 'test', ...args]);
这意味着:
| 维度 | yuantest-playwright | allure-playwright |
|---|---|---|
| 定位 | 全栈测试管理平台 | 报告生成器 |
| 实时性 | ✅ WebSocket 实时推送 | ❌ 测试结束后生成报告 |
| Web Dashboard | ✅ 内置 React Dashboard | ✅ Allure Server (需额外部署) |
| Flaky 管理 | ✅ 自动检测+隔离+统计 | ❌ 无 |
| 测试编排 | ✅ 智能分片+负载均衡 | ❌ 无 |
| 测试执行 | ✅ 内置 Executor | ❌ 需外部执行 |
| 历史趋势 | ✅ 内置存储 | ✅ 需配置 History |
| 失败分析 | ✅ 自动分类+修复建议 | ⚠️ 需手动分析 |
| 国际化 | ✅ 中英文 | ⚠️ 需自行配置 |
| 部署复杂度 | ✅ 单 npm 包 | ⚠️ 需 Allure Server |
| 报告美观度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 生态成熟度 | 新兴项目 | 成熟生态 |
| CI/CD 集成 | ✅ CLI + API | ✅ 广泛支持 |
| yuantest-playwright 优势 | allure-playwright 优势 |
|---|---|
| 一体化解决方案 | 报告视觉效果更精美 |
| 实时监控测试进度 | 生态成熟、社区大 |
| Flaky 测试管理 | 支持多种测试框架 |
| 智能测试编排 | 历史趋势图表丰富 |
| 部署简单 | 插件扩展性强 |
使用 yuantest-playwright 进行日常测试管理和实时监控,同时集成 allure-playwright 生成精美的最终报告:
# 日常开发:使用 yuantest 实时监控
yuantest run --test-dir ./tests
# CI/CD:生成 Allure 报告归档
npx playwright test --reporter=allure-playwright
# 全局安装
npm install -g yuantest-playwright
# 或作为项目依赖
npm install --save-dev yuantest-playwright
git clone https://github.com/yuandiv/yuantest-playwright.git
cd yuantest-playwright
npm install
npm run build
npm link
# 基本用法
yuantest run --test-dir ./tests
# 指定项目名称和输出目录
yuantest run --project my-app --test-dir ./e2e --output ./reports
# 使用 4 个分片并行执行
yuantest run --test-dir ./tests --shards 4
# 指定多个浏览器
yuantest run --test-dir ./tests --browsers chromium,firefox
# 设置超时和重试
yuantest run --test-dir ./tests --timeout 60000 --retries 2
# 默认端口 5274
yuantest ui
# 自定义端口
yuantest ui --port 8080
# 自定义报告和数据目录
yuantest ui --port 5274 --output ./reports --data ./test-data
然后在浏览器打开 http://localhost:5274 查看可视化界面。
yuantest --help
yuantest run --help
yuantest ui --help
| 参数 | 简写 | 说明 | 默认值 |
|---|---|---|---|
--project |
-p |
项目名称 | test-project |
--test-dir |
-t |
测试文件目录 | ./tests |
--output |
-o |
输出目录 | ./test-output |
--shards |
-s |
分片数量 | 1 |
--workers |
-w |
Worker 数量 | 1 |
--browsers |
-b |
浏览器列表(逗号分隔) | chromium |
--base-url |
基础 URL | ||
--timeout |
超时时间(ms) | 30000 | |
--retries |
重试次数 | 0 | |
--grep |
运行匹配的测试 | ||
--update-snapshots |
更新快照 | false |
# 查看测试分片分配方案
yuantest orchestrate --test-dir ./tests --shards 4
# 查看最近 10 条报告
yuantest report --limit 10
# 查看指定报告
yuentest report --id run_20240101_120000_abc123
# 查看 Flaky 统计
yuantest flaky
# 列出所有 Flaky 测试
yuantest flaky --list
# 列出已隔离的测试
yuantest flaky --quarantined
# 隔离指定测试
yuantest flaky --quarantine <test-id>
# 释放指定测试
yuantest flaky --release <test-id>
# 自定义阈值
yuantest flaky --list --threshold 0.5
# 分析指定 Run 的失败原因
yuantest analyze --id run_20240101_120000_abc123
启动后访问 http://localhost:<port>,包含以下功能模块:
Dashboard 提供 RESTful API,方便集成到其他系统:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/health |
健康检查 |
| GET | /api/stats |
总体统计 |
| GET | /api/runs |
运行列表 |
| GET | /api/runs/:id |
运行详情 |
| GET | /api/flaky |
Flaky 测试列表 |
| GET | /api/flaky/quarantined |
已隔离测试 |
| POST | /api/flaky/:id/quarantine |
隔离测试 |
| POST | /api/flaky/:id/release |
释放测试 |
| GET | /api/flaky/stats |
Flaky 统计 |
| GET | /api/analysis/:runId |
失败分析 |
| GET | /api/progress |
实时进度 |
import {
Orchestrator,
Executor,
Reporter,
FlakyTestManager,
DashboardServer,
} from 'yuantest-playwright';
async function main() {
// 1. 编排测试
const orchestrator = new Orchestrator({
projectName: 'my-app',
testDir: './e2e',
outputDir: './reports',
shards: 4,
browsers: ['chromium', 'firefox'],
});
await orchestrator.initialize();
const plan = await orchestrator.orchestrate();
// 2. 执行测试
const executor = new Executor(orchestrator.getConfig());
// 监听事件
executor.on('run_started', (data) => {
console.log(`Run started: ${data.runId}`);
});
executor.on('test_result', (result) => {
console.log(`[${result.status}] ${result.title} (${result.duration}ms)`);
});
executor.on('run_progress', (progress) => {
console.log(`Progress: ${progress.passed}/${progress.totalTests} passed`);
});
executor.on('output', (data) => {
process.stdout.write(data.data);
});
executor.on('run_completed', async (result) => {
// 3. 生成报告
const reporter = new Reporter('./reports');
const reportPath = await reporter.generateReport(result);
console.log(`Report: ${reportPath}`);
// 4. 分析失败
const analysis = await reporter.analyzeFailures(result);
console.log(`Failures: ${analysis.length}`);
});
const result = await executor.execute({
grepPattern: 'smoke',
projectFilter: 'chromium',
updateSnapshots: false,
});
console.log(`Final: ${result.passed}/${result.totalTests} passed`);
// 5. 启动 Dashboard
const server = new DashboardServer(5274, './reports', './test-data');
await server.start();
}
main();
import { FlakyTestManager, AnnotationManager } from 'yuantest-playwright';
// Flaky 测试管理
const flakyManager = new FlakyTestManager('./test-data');
await flakyManager.initialize();
// 获取 Flaky 测试
const flakyTests = await flakyManager.getFlakyTests(0.3);
console.log(`Found ${flakyTests.length} flaky tests`);
// 隔离测试
await flakyManager.quarantineTest('test-id-123');
// 注解管理
const annotationManager = new AnnotationManager('./tests');
const annotations = await annotationManager.scanAnnotations();
console.log(`Found ${annotations.length} annotated tests`);
yuantest-playwright/
├── bin/
│ ├── cli.js # CLI 入口
│ └── start-ui.js # Dashboard 启动脚本
├── dashboard/ # Web Dashboard 前端源码
│ ├── src/
│ │ ├── components/ # React 组件
│ │ ├── hooks/ # 自定义 Hooks
│ │ ├── services/ # API 服务
│ │ └── types/ # TypeScript 类型
│ └── index.html
├── src/
│ ├── index.ts # 主入口
│ ├── types/ # 类型定义
│ ├── orchestrator/ # 测试编排器
│ ├── executor/ # 测试执行器
│ ├── reporter/ # 报告生成器
│ ├── realtime/ # 实时报告
│ ├── flaky/ # Flaky 管理
│ ├── config/ # 配置管理
│ ├── trace/ # Trace 管理
│ ├── annotations/ # 注解扫描
│ ├── tags/ # 标签管理
│ ├── artifacts/ # 产物管理
│ ├── visual/ # 视觉测试
│ ├── logger/ # 日志模块
│ ├── cli/ # CLI 命令
│ └── ui/ # Dashboard 服务器
├── tests/ # 测试文件
├── docs/ # 文档
└── package.json
# GitHub Actions 示例
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run E2E tests
run: |
npm install -g yuantest-playwright
yuantest run --test-dir ./e2e --shards 4 --output ./reports
- name: Upload reports
uses: actions/upload-artifact@v3
with:
name: test-reports
path: reports/
# 使用智能分片加速大型测试套件
yuantest run --test-dir ./e2e --shards 8 --workers 4
# 隔离 Flaky 测试避免阻塞 CI
yuantest flaky --quarantine-all
yuantest run --test-dir ./e2e
# 在所有浏览器上运行测试
yuantest run --test-dir ./e2e --browsers chromium,firefox,webkit
# 仅在特定浏览器上运行
yuantest run --test-dir ./e2e --browsers chromium
支持通过配置文件自定义行为:
// yuantest.config.ts
import { defineConfig } from 'yuantest-playwright';
export default defineConfig({
project: 'my-app',
testDir: './e2e',
outputDir: './reports',
shards: 4,
browsers: ['chromium', 'firefox'],
timeout: 60000,
retries: 2,
flaky: {
threshold: 0.3,
autoQuarantine: false,
},
dashboard: {
port: 5274,
open: true,
},
});
欢迎贡献代码、报告问题或提出建议!
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)查看 CONTRIBUTING.md 了解详情。
MIT © YuanDiv
感谢以下开源项目:
如果这个项目对你有帮助,请给一个 ⭐️ Star!