feat: configure UAT test automation and reporting

This commit is contained in:
张翔
2026-03-25 09:52:27 +08:00
parent d7ad5776f8
commit f0efbaeabd
6 changed files with 329 additions and 0 deletions
+23
View File
@@ -67,6 +67,26 @@ pipeline:
depends_on:
- start-test-env
# UAT测试阶段
uat-tests:
image: mcr.microsoft.com/playwright:v1.58.2-jammy
group: uat
environment:
TEST_BASE_URL: http://frontend-test:80
API_BASE_URL: http://backend-test:8080
HEADLESS_BROWSER: "true"
CI: true
commands:
- cd uat-tests
- npm ci
- npx playwright install --with-deps chromium
- npx playwright test --config=playwright.config.ts --reporter=json --reporter=html --reporter=junit
- node quality-gate.js
when:
event: [push, pull_request]
depends_on:
- start-test-env
# 性能测试阶段
performance-tests:
image: node:18-alpine
@@ -80,6 +100,8 @@ pipeline:
when:
event: [push, pull_request]
branch: [main, develop]
depends_on:
- uat-tests
# 质量门禁检查
quality-gate:
@@ -119,6 +141,7 @@ pipeline:
depends_on:
- quality-gate
- trend-analysis
- uat-tests
# 生成测试报告
generate-reports:
+139
View File
@@ -0,0 +1,139 @@
# UAT Test Suite
UAT测试套件用于验证Novalon管理系统的用户验收测试场景。
## 目录结构
```
uat-tests/
├── config/ # 配置文件
│ └── uat-config.ts # UAT配置
├── data/ # 测试数据
│ ├── users.json # 用户数据
│ ├── roles.json # 角色数据
│ └── scenarios.json # 场景数据
├── scenarios/ # 测试场景
│ ├── user-lifecycle/ # 用户生命周期场景
│ ├── role-management/ # 角色管理场景
│ ├── collaboration/ # 多角色协作场景
│ ├── permission/ # 权限验证场景
│ └── audit/ # 审计场景
├── utils/ # 工具类
│ ├── uat-helper.ts # UAT辅助工具
│ ├── scenario-runner.ts # 场景运行器
│ └── data-loader.ts # 数据加载器
├── pages/ # 页面对象
│ └── UserManagementPage.ts
├── screenshots/ # 截图目录
├── test-results/ # 测试结果
├── playwright.config.ts # Playwright配置
├── run-uat-tests.sh # 测试运行脚本
├── quality-gate.js # 质量门禁检查
└── package.json # 依赖配置
```
## 快速开始
### 安装依赖
```bash
cd uat-tests
npm install
npx playwright install --with-deps
```
### 配置环境变量
```bash
cp .env.example .env
# 编辑.env文件,设置测试环境URL
```
### 运行测试
```bash
# 运行所有UAT测试
npm run test
# 运行特定场景
npx playwright test scenarios/user-lifecycle/
# 调试模式
npm run test:debug
# 查看测试报告
npm run test:report
```
## 测试场景
### 用户生命周期场景
- 新用户注册与激活
- 用户信息变更
- 用户角色演进
### 角色管理场景
- 角色分配与权限验证
### 多角色协作场景
- 跨部门协作流程
- 数据一致性验证
## 质量门禁
质量门禁标准:
- 通过率 >= 95%
- 不稳定率 <= 5%
- 执行时间 <= 10分钟
运行质量门禁检查:
```bash
npm run test:quality-gate
```
## CI/CD集成
UAT测试已集成到Woodpecker CI/CD流水线中,在每次push和pull request时自动运行。
## 最佳实践
1. **测试数据隔离**:每个测试使用独立的数据,避免相互影响
2. **智能等待**:使用UATHelper提供的智能等待方法,避免固定等待
3. **截图记录**:测试失败时自动截图,便于调试
4. **并行执行**:支持多worker并行执行,提高测试效率
5. **跨浏览器测试**:支持Chrome、Firefox、Safari浏览器测试
## 故障排查
### 测试失败
1. 查看测试报告:`npm run test:report`
2. 检查截图:`screenshots/`目录
3. 查看日志:`test-results/`目录
### 环境问题
确保测试环境已启动:
```bash
cd ..
docker-compose -f docker-compose.test.yml up -d
```
## 贡献指南
添加新的UAT测试场景:
1.`scenarios/`目录下创建新的场景文件
2. 使用`ScenarioRunner``UATHelper`工具
3. 遵循现有的测试模式和命名约定
4. 添加相应的测试数据到`data/`目录
## 许可证
Copyright © 2024 Novalon. All rights reserved.
+16
View File
@@ -0,0 +1,16 @@
{
"name": "novalon-uat-tests",
"version": "1.0.0",
"description": "UAT test suite for Novalon Management System",
"scripts": {
"test": "playwright test",
"test:headed": "playwright test --headed",
"test:debug": "playwright test --debug",
"test:report": "playwright show-report",
"test:quality-gate": "node quality-gate.js",
"install-browsers": "playwright install --with-deps"
},
"devDependencies": {
"@playwright/test": "^1.40.0"
}
}
+39
View File
@@ -0,0 +1,39 @@
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './uat-tests/scenarios',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 4 : 8,
reporter: [
['html', { outputFolder: 'uat-tests/test-results/html-report' }],
['json', { outputFile: 'uat-tests/test-results/results.json' }],
['junit', { outputFile: 'uat-tests/test-results/junit.xml' }],
['list']
],
use: {
baseURL: process.env.TEST_BASE_URL || 'http://localhost:3001',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
headless: process.env.HEADLESS_BROWSER === 'true',
actionTimeout: parseInt(process.env.TEST_TIMEOUT || '30000'),
navigationTimeout: parseInt(process.env.TEST_TIMEOUT || '30000'),
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
outputDir: 'uat-tests/test-results/artifacts',
});
+86
View File
@@ -0,0 +1,86 @@
const fs = require('fs');
const path = require('path');
const resultsPath = path.join(__dirname, 'test-results', 'results.json');
const qualityGateThresholds = {
passRate: 95,
flakyRate: 5,
duration: 600000
};
function loadTestResults() {
if (!fs.existsSync(resultsPath)) {
console.error('❌ Test results not found!');
process.exit(1);
}
const data = fs.readFileSync(resultsPath, 'utf-8');
return JSON.parse(data);
}
function calculateMetrics(results) {
const totalTests = results.stats.expected;
const passedTests = results.stats.expected - results.stats.failed;
const failedTests = results.stats.failed;
const flakyTests = results.stats.flaky;
const duration = results.stats.duration;
const passRate = (passedTests / totalTests) * 100;
const flakyRate = (flakyTests / totalTests) * 100;
return {
totalTests,
passedTests,
failedTests,
flakyTests,
duration,
passRate: passRate.toFixed(2),
flakyRate: flakyRate.toFixed(2)
};
}
function checkQualityGate(metrics) {
const failures = [];
if (metrics.passRate < qualityGateThresholds.passRate) {
failures.push(`Pass rate (${metrics.passRate}%) is below threshold (${qualityGateThresholds.passRate}%)`);
}
if (metrics.flakyRate > qualityGateThresholds.flakyRate) {
failures.push(`Flaky rate (${metrics.flakyRate}%) is above threshold (${qualityGateThresholds.flakyRate}%)`);
}
if (metrics.duration > qualityGateThresholds.duration) {
failures.push(`Test duration (${metrics.duration}ms) exceeds threshold (${qualityGateThresholds.duration}ms)`);
}
return failures;
}
function main() {
console.log('🚦 Checking UAT Quality Gate...\n');
const results = loadTestResults();
const metrics = calculateMetrics(results);
const failures = checkQualityGate(metrics);
console.log('📊 Test Metrics:');
console.log(` Total Tests: ${metrics.totalTests}`);
console.log(` Passed: ${metrics.passedTests}`);
console.log(` Failed: ${metrics.failedTests}`);
console.log(` Flaky: ${metrics.flakyTests}`);
console.log(` Pass Rate: ${metrics.passRate}%`);
console.log(` Flaky Rate: ${metrics.flakyRate}%`);
console.log(` Duration: ${metrics.duration}ms\n`);
if (failures.length === 0) {
console.log('✅ Quality Gate Passed!');
process.exit(0);
} else {
console.log('❌ Quality Gate Failed:');
failures.forEach(failure => console.log(` - ${failure}`));
process.exit(1);
}
}
main();
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
set -e
echo "🚀 Starting UAT Test Suite..."
cd "$(dirname "$0")"
if [ ! -f ".env" ]; then
echo "⚠️ Warning: .env file not found, using default values"
cp .env.example .env
fi
export $(cat .env | xargs)
echo "📊 Running UAT tests..."
npx playwright test --config=playwright.config.ts
if [ $? -eq 0 ]; then
echo "✅ All UAT tests passed!"
echo "📈 Generating test report..."
npx playwright show-report uat-tests/test-results/html-report
else
echo "❌ Some tests failed. Check the report for details."
exit 1
fi