docs: 删除过时的文档和测试报告文件
删除不再需要的文档、测试报告和计划文件,包括标题层级规范、颜色优化报告、测试框架文档等
This commit is contained in:
@@ -1,184 +0,0 @@
|
||||
# E2E测试环境配置指南
|
||||
|
||||
## 环境说明
|
||||
|
||||
本项目支持三个测试环境:
|
||||
|
||||
- **development**: 本地开发环境 (http://localhost:3001)
|
||||
- **staging**: 预发布环境
|
||||
- **production**: 生产环境
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 配置环境变量
|
||||
|
||||
复制环境变量示例文件:
|
||||
|
||||
```bash
|
||||
cp e2e/.env.example e2e/.env
|
||||
```
|
||||
|
||||
### 2. 运行测试
|
||||
|
||||
#### 开发环境测试
|
||||
|
||||
```bash
|
||||
# 默认使用development环境
|
||||
npm run test:e2e
|
||||
|
||||
# 或者显式指定
|
||||
TEST_ENV=development npm run test:e2e
|
||||
```
|
||||
|
||||
#### 预发布环境测试
|
||||
|
||||
```bash
|
||||
TEST_ENV=staging npm run test:e2e
|
||||
```
|
||||
|
||||
#### 生产环境测试
|
||||
|
||||
```bash
|
||||
TEST_ENV=production npm run test:e2e
|
||||
```
|
||||
|
||||
## 环境配置详解
|
||||
|
||||
### Development环境
|
||||
|
||||
- **baseURL**: http://localhost:3001
|
||||
- **headless**: false (显示浏览器窗口)
|
||||
- **slowMo**: 100ms (减慢操作速度,便于调试)
|
||||
- **retries**: 0 (不重试)
|
||||
- **webServer**: 自动启动开发服务器
|
||||
|
||||
### Staging环境
|
||||
|
||||
- **baseURL**: https://staging.novalon.com
|
||||
- **headless**: true (无头模式)
|
||||
- **slowMo**: 0 (正常速度)
|
||||
- **retries**: 1 (失败重试1次)
|
||||
- **webServer**: 不启动
|
||||
|
||||
### Production环境
|
||||
|
||||
- **baseURL**: https://novalon.com
|
||||
- **headless**: true (无头模式)
|
||||
- **slowMo**: 0 (正常速度)
|
||||
- **retries**: 2 (失败重试2次)
|
||||
- **webServer**: 不启动
|
||||
|
||||
## 环境变量
|
||||
|
||||
| 变量名 | 说明 | 默认值 |
|
||||
|--------|------|--------|
|
||||
| TEST_ENV | 测试环境 | development |
|
||||
| BASE_URL | 基础URL | 根据环境配置 |
|
||||
| API_URL | API URL | 根据环境配置 |
|
||||
| HEADLESS | 无头模式 | true |
|
||||
| SLOW_MO | 减慢操作(ms) | 0 |
|
||||
| TIMEOUT | 超时时间(ms) | 120000 |
|
||||
| RETRIES | 重试次数 | 0 |
|
||||
| SCREENSHOT | 截图策略 | only-on-failure |
|
||||
| VIDEO | 视频策略 | retain-on-failure |
|
||||
| TRACE | 追踪策略 | retain-on-failure |
|
||||
| CI | CI环境 | false |
|
||||
| DEBUG | 调试模式 | false |
|
||||
| PWDEBUG | Playwright调试 | false |
|
||||
|
||||
## CI/CD集成
|
||||
|
||||
### Woodpecker CI配置示例
|
||||
|
||||
```yaml
|
||||
pipeline:
|
||||
test-smoke:
|
||||
image: mcr.microsoft.com/playwright:v1.48.0-focal
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm ci
|
||||
- TEST_ENV=staging npx playwright test --project=chromium --grep=@smoke
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
|
||||
test-regression:
|
||||
image: mcr.microsoft.com/playwright:v1.48.0-focal
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm ci
|
||||
- TEST_ENV=staging npx playwright test --project=chromium --grep=@regression
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
|
||||
test-full:
|
||||
image: mcr.microsoft.com/playwright:v1.48.0-focal
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm ci
|
||||
- TEST_ENV=production npx playwright test
|
||||
when:
|
||||
event: [deployment]
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 本地开发
|
||||
|
||||
使用development环境,可以看到浏览器操作过程,便于调试:
|
||||
|
||||
```bash
|
||||
TEST_ENV=development npm run test:e2e
|
||||
```
|
||||
|
||||
### 2. 代码提交
|
||||
|
||||
在staging环境运行smoke和regression测试:
|
||||
|
||||
```bash
|
||||
TEST_ENV=staging npm run test:e2e -- --grep="@smoke|@regression"
|
||||
```
|
||||
|
||||
### 3. 生产部署
|
||||
|
||||
在production环境运行完整测试套件:
|
||||
|
||||
```bash
|
||||
TEST_ENV=production npm run test:e2e
|
||||
```
|
||||
|
||||
### 4. 调试测试
|
||||
|
||||
启用Playwright调试模式:
|
||||
|
||||
```bash
|
||||
PWDEBUG=1 TEST_ENV=development npm run test:e2e -- --grep="test name"
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 问题1: 环境变量不生效
|
||||
|
||||
确保在项目根目录运行命令,或者在e2e目录下运行。
|
||||
|
||||
### 问题2: 开发服务器启动失败
|
||||
|
||||
检查端口3001是否被占用,或者修改配置中的端口。
|
||||
|
||||
### 问题3: 测试超时
|
||||
|
||||
增加TIMEOUT环境变量值:
|
||||
|
||||
```bash
|
||||
TIMEOUT=180000 npm run test:e2e
|
||||
```
|
||||
|
||||
### 问题4: 网络问题
|
||||
|
||||
检查网络连接,确保可以访问目标环境URL。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [测试数据管理](./test-data-management.md)
|
||||
- [性能测试指南](./performance-testing.md)
|
||||
- [安全测试指南](./security-testing.md)
|
||||
- [可访问性测试指南](./accessibility-testing.md)
|
||||
@@ -1,674 +0,0 @@
|
||||
# Allure测试报告系统使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
Allure是一个灵活的、轻量级的多语言测试报告工具,能够生成美观、详细的测试报告。本文档介绍如何在E2E测试项目中集成和使用Allure报告系统。
|
||||
|
||||
---
|
||||
|
||||
## 一、安装和配置
|
||||
|
||||
### 1.1 安装依赖
|
||||
|
||||
```bash
|
||||
cd e2e
|
||||
npm install --save-dev @playwright/test allure-playwright allure-commandline
|
||||
```
|
||||
|
||||
### 1.2 配置Playwright
|
||||
|
||||
在`playwright.config.ts`中添加Allure reporter:
|
||||
|
||||
```typescript
|
||||
export default defineConfig({
|
||||
reporter: [
|
||||
['html', { open: 'never' }],
|
||||
['json', { outputFile: 'test-results/results.json' }],
|
||||
['junit', { outputFile: 'test-results/junit.xml' }],
|
||||
['line'],
|
||||
['list'],
|
||||
['allure-playwright', {
|
||||
outputFolder: 'allure-results',
|
||||
detail: true,
|
||||
suiteTitle: false,
|
||||
}],
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
### 1.3 添加npm脚本
|
||||
|
||||
在`package.json`中添加Allure相关脚本:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"test": "playwright test",
|
||||
"test:allure": "allure generate allure-results --clean -o allure-report",
|
||||
"test:allure:open": "allure open allure-report",
|
||||
"test:allure:serve": "allure serve allure-results"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、基本使用
|
||||
|
||||
### 2.1 运行测试并生成报告
|
||||
|
||||
```bash
|
||||
# 1. 运行测试
|
||||
npm run test
|
||||
|
||||
# 2. 生成Allure报告
|
||||
npm run test:allure
|
||||
|
||||
# 3. 打开报告
|
||||
npm run test:allure:open
|
||||
```
|
||||
|
||||
### 2.2 实时查看报告
|
||||
|
||||
```bash
|
||||
# 在测试运行时实时查看报告
|
||||
npm run test:allure:serve
|
||||
```
|
||||
|
||||
### 2.3 清理历史报告
|
||||
|
||||
```bash
|
||||
# 清理旧的报告数据
|
||||
rm -rf allure-results allure-report
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、Allure注解
|
||||
|
||||
### 3.1 测试描述
|
||||
|
||||
使用`@allure.description`添加测试描述:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('测试用例描述', async ({ page }) => {
|
||||
allure.description('这是一个测试用例的详细描述');
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 3.2 测试步骤
|
||||
|
||||
使用`allure.step`添加测试步骤:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('测试步骤示例', async ({ page }) => {
|
||||
await allure.step('步骤1: 打开首页', async () => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
await allure.step('步骤2: 点击导航链接', async () => {
|
||||
await page.click('nav a');
|
||||
});
|
||||
|
||||
await allure.step('步骤3: 验证页面加载', async () => {
|
||||
await expect(page).toHaveURL('/about');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 3.3 测试标签
|
||||
|
||||
使用`@allure.tag`添加测试标签:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('测试标签示例', async ({ page }) => {
|
||||
allure.tags('smoke', 'regression', 'high-priority');
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 3.4 测试严重级别
|
||||
|
||||
使用`@allure.severity`添加测试严重级别:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('测试严重级别示例', async ({ page }) => {
|
||||
allure.severity('critical');
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
支持的严重级别:
|
||||
- `blocker`: 阻塞级别
|
||||
- `critical`: 严重级别
|
||||
- `normal`: 普通级别
|
||||
- `minor`: 次要级别
|
||||
- `trivial`: 微不足道级别
|
||||
|
||||
### 3.5 测试套件
|
||||
|
||||
使用`@allure.suite`添加测试套件:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test.describe('测试套件示例', () => {
|
||||
test.beforeEach(async () => {
|
||||
allure.suite('首页测试');
|
||||
});
|
||||
|
||||
test('测试用例1', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
test('测试用例2', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 3.6 测试链接
|
||||
|
||||
使用`@allure.link`添加测试链接:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('测试链接示例', async ({ page }) => {
|
||||
allure.link('https://example.com/ticket/123', 'JIRA链接');
|
||||
allure.issue('123', 'JIRA问题');
|
||||
allure.tms('456', '测试用例管理');
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 3.7 附件
|
||||
|
||||
使用`allure.attachment`添加附件:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('附件示例', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
// 添加截图附件
|
||||
const screenshot = await page.screenshot();
|
||||
allure.attachment('首页截图', screenshot, 'image/png');
|
||||
|
||||
// 添加文本附件
|
||||
allure.attachment('页面URL', page.url(), 'text/plain');
|
||||
|
||||
// 添加JSON附件
|
||||
const data = { key: 'value' };
|
||||
allure.attachment('测试数据', JSON.stringify(data), 'application/json');
|
||||
});
|
||||
```
|
||||
|
||||
### 3.8 测试参数
|
||||
|
||||
使用`@allure.parameter`添加测试参数:
|
||||
|
||||
```typescript
|
||||
import { test } from '@playwright/test';
|
||||
import { allure } from 'allure-playwright';
|
||||
|
||||
test('测试参数示例', async ({ page }) => {
|
||||
const browser = 'chromium';
|
||||
const viewport = { width: 1280, height: 720 };
|
||||
|
||||
allure.parameter('浏览器', browser);
|
||||
allure.parameter('视口大小', `${viewport.width}x${viewport.height}`);
|
||||
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、高级功能
|
||||
|
||||
### 4.1 环境信息
|
||||
|
||||
创建`allure-results/environment.properties`文件:
|
||||
|
||||
```properties
|
||||
# Environment Properties
|
||||
Browser=Chromium
|
||||
Browser.Version=120.0.0
|
||||
OS=macOS
|
||||
OS.Version=14.0
|
||||
Environment=staging
|
||||
BaseURL=https://staging.novalon.com
|
||||
```
|
||||
|
||||
### 4.2 测试分类
|
||||
|
||||
创建`allure-results/categories.json`文件:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "Ignored tests",
|
||||
"matchedStatuses": ["skipped"]
|
||||
},
|
||||
{
|
||||
"name": "Infrastructure problems",
|
||||
"matchedStatuses": ["broken", "failed"],
|
||||
"messageRegex": ".*Connection refused.*"
|
||||
},
|
||||
{
|
||||
"name": "Outdated tests",
|
||||
"matchedStatuses": ["broken"],
|
||||
"traceRegex": ".*FileNotFoundException.*"
|
||||
},
|
||||
{
|
||||
"name": "Product defects",
|
||||
"matchedStatuses": ["failed"]
|
||||
},
|
||||
{
|
||||
"name": "Test defects",
|
||||
"matchedStatuses": ["broken"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 4.3 自定义测试执行器
|
||||
|
||||
创建`allure-results/executor.json`文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Woodpecker CI",
|
||||
"type": "woodpecker",
|
||||
"url": "https://ci.example.com",
|
||||
"buildOrder": "123",
|
||||
"buildName": "E2E Tests #123",
|
||||
"buildUrl": "https://ci.example.com/build/123",
|
||||
"reportUrl": "https://ci.example.com/build/123/allure",
|
||||
"reportName": "Allure Report"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、CI/CD集成
|
||||
|
||||
### 5.1 Woodpecker CI集成
|
||||
|
||||
```yaml
|
||||
# .woodpecker.yml
|
||||
steps:
|
||||
- name: Run Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm ci
|
||||
- npm run test
|
||||
environment:
|
||||
ALLURE_RESULTS_PATH: allure-results
|
||||
|
||||
- name: Generate Allure Report
|
||||
image: frankescobar/allure-docker-service
|
||||
commands:
|
||||
- cd e2e
|
||||
- allure generate allure-results --clean -o allure-report
|
||||
when:
|
||||
status: [success, failure]
|
||||
|
||||
- name: Upload Allure Report
|
||||
image: plugins/s3
|
||||
settings:
|
||||
bucket: test-reports
|
||||
source: e2e/allure-report/**
|
||||
target: /allure/${CI_COMMIT_SHA}
|
||||
when:
|
||||
status: [success, failure]
|
||||
```
|
||||
|
||||
### 5.2 GitHub Actions集成
|
||||
|
||||
```yaml
|
||||
# .github/workflows/e2e-tests.yml
|
||||
name: E2E Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd e2e
|
||||
npm ci
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd e2e
|
||||
npm run test
|
||||
|
||||
- name: Generate Allure Report
|
||||
run: |
|
||||
cd e2e
|
||||
npm run test:allure
|
||||
|
||||
- name: Upload Allure Report
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: allure-report
|
||||
path: e2e/allure-report
|
||||
```
|
||||
|
||||
### 5.3 GitLab CI集成
|
||||
|
||||
```yaml
|
||||
# .gitlab-ci.yml
|
||||
stages:
|
||||
- test
|
||||
- report
|
||||
|
||||
test:
|
||||
stage: test
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
script:
|
||||
- cd e2e
|
||||
- npm ci
|
||||
- npm run test
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- e2e/allure-results/
|
||||
expire_in: 1 week
|
||||
|
||||
report:
|
||||
stage: report
|
||||
image: frankescobar/allure-docker-service
|
||||
script:
|
||||
- cd e2e
|
||||
- allure generate allure-results --clean -o allure-report
|
||||
- allure open allure-report
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- e2e/allure-report/
|
||||
expire_in: 1 week
|
||||
dependencies:
|
||||
- test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、报告分析
|
||||
|
||||
### 6.1 测试概览
|
||||
|
||||
Allure报告提供以下概览信息:
|
||||
- 测试总数
|
||||
- 通过/失败/跳过的测试数量
|
||||
- 测试执行时间
|
||||
- 测试通过率
|
||||
- 测试趋势
|
||||
|
||||
### 6.2 测试套件
|
||||
|
||||
按测试套件查看测试结果:
|
||||
- 每个套件的测试数量
|
||||
- 每个套件的通过率
|
||||
- 每个套件的执行时间
|
||||
|
||||
### 6.3 测试用例
|
||||
|
||||
查看每个测试用例的详细信息:
|
||||
- 测试描述
|
||||
- 测试步骤
|
||||
- 测试参数
|
||||
- 测试附件
|
||||
- 测试日志
|
||||
- 测试截图
|
||||
|
||||
### 6.4 测试趋势
|
||||
|
||||
查看测试趋势图表:
|
||||
- 测试通过率趋势
|
||||
- 测试执行时间趋势
|
||||
- 测试数量趋势
|
||||
|
||||
### 6.5 测试分类
|
||||
|
||||
按分类查看测试结果:
|
||||
- Ignored tests(被忽略的测试)
|
||||
- Infrastructure problems(基础设施问题)
|
||||
- Outdated tests(过时的测试)
|
||||
- Product defects(产品缺陷)
|
||||
- Test defects(测试缺陷)
|
||||
|
||||
---
|
||||
|
||||
## 七、最佳实践
|
||||
|
||||
### 7.1 使用描述性测试名称
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法
|
||||
test('应该能够成功提交联系表单', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
// ❌ 不好的做法
|
||||
test('测试1', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 7.2 添加详细的测试步骤
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法
|
||||
test('完整的测试步骤', async ({ page }) => {
|
||||
await allure.step('步骤1: 打开首页', async () => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
await allure.step('步骤2: 填写联系表单', async () => {
|
||||
await page.fill('input[name="name"]', '张三');
|
||||
await page.fill('input[name="email"]', 'zhangsan@example.com');
|
||||
await page.fill('input[name="phone"]', '13800138000');
|
||||
await page.fill('textarea[name="message"]', '测试消息');
|
||||
});
|
||||
|
||||
await allure.step('步骤3: 提交表单', async () => {
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForSelector('.success');
|
||||
});
|
||||
});
|
||||
|
||||
// ❌ 不好的做法
|
||||
test('没有测试步骤', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.fill('input[name="name"]', '张三');
|
||||
await page.fill('input[name="email"]', 'zhangsan@example.com');
|
||||
await page.fill('input[name="phone"]', '13800138000');
|
||||
await page.fill('textarea[name="message"]', '测试消息');
|
||||
await page.click('button[type="submit"]');
|
||||
await page.waitForSelector('.success');
|
||||
});
|
||||
```
|
||||
|
||||
### 7.3 使用测试标签
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法
|
||||
test('带标签的测试', async ({ page }) => {
|
||||
allure.tags('smoke', 'regression', 'high-priority');
|
||||
allure.severity('critical');
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
// ❌ 不好的做法
|
||||
test('没有标签的测试', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 7.4 添加测试附件
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法
|
||||
test('带附件的测试', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
||||
const screenshot = await page.screenshot();
|
||||
allure.attachment('首页截图', screenshot, 'image/png');
|
||||
|
||||
const pageContent = await page.content();
|
||||
allure.attachment('页面HTML', pageContent, 'text/html');
|
||||
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
// ❌ 不好的做法
|
||||
test('没有附件的测试', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 7.5 使用测试参数
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法
|
||||
test('带参数的测试', async ({ page }) => {
|
||||
const testData = {
|
||||
name: '张三',
|
||||
email: 'zhangsan@example.com',
|
||||
phone: '13800138000',
|
||||
};
|
||||
|
||||
allure.parameter('测试数据', JSON.stringify(testData));
|
||||
allure.parameter('浏览器', 'chromium');
|
||||
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
// ❌ 不好的做法
|
||||
test('没有参数的测试', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 八、故障排查
|
||||
|
||||
### 8.1 报告生成失败
|
||||
|
||||
**问题**: 运行`npm run test:allure`时报告生成失败。
|
||||
|
||||
**原因**: `allure-results`目录不存在或为空。
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 确保先运行测试
|
||||
npm run test
|
||||
|
||||
# 检查allure-results目录
|
||||
ls -la allure-results
|
||||
|
||||
# 如果目录为空,重新运行测试
|
||||
rm -rf allure-results
|
||||
npm run test
|
||||
```
|
||||
|
||||
### 8.2 报告打开失败
|
||||
|
||||
**问题**: 运行`npm run test:allure:open`时报告无法打开。
|
||||
|
||||
**原因**: `allure-report`目录不存在或Allure未正确安装。
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 重新生成报告
|
||||
npm run test:allure
|
||||
|
||||
# 检查allure-report目录
|
||||
ls -la allure-report
|
||||
|
||||
# 重新安装Allure
|
||||
npm install --save-dev allure-commandline
|
||||
```
|
||||
|
||||
### 8.3 测试步骤不显示
|
||||
|
||||
**问题**: Allure报告中没有显示测试步骤。
|
||||
|
||||
**原因**: 没有使用`allure.step`添加测试步骤。
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 添加测试步骤
|
||||
await allure.step('步骤描述', async () => {
|
||||
// 测试逻辑
|
||||
});
|
||||
```
|
||||
|
||||
### 8.4 附件不显示
|
||||
|
||||
**问题**: Allure报告中没有显示附件。
|
||||
|
||||
**原因**: 没有使用`allure.attachment`添加附件或附件路径不正确。
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 添加附件
|
||||
const screenshot = await page.screenshot();
|
||||
allure.attachment('截图', screenshot, 'image/png');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、总结
|
||||
|
||||
Allure测试报告系统提供了强大的测试报告功能,包括:
|
||||
|
||||
1. **美观的报告界面**: 直观的UI设计,易于理解
|
||||
2. **详细的测试信息**: 测试描述、步骤、参数、附件等
|
||||
3. **测试趋势分析**: 通过率、执行时间、测试数量趋势
|
||||
4. **测试分类**: 按缺陷类型分类,便于问题定位
|
||||
5. **CI/CD集成**: 支持多种CI/CD工具集成
|
||||
|
||||
通过使用Allure报告系统,可以更好地了解测试执行情况,快速定位问题,提高测试效率。
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2026-02-28
|
||||
**维护者**: 张翔
|
||||
@@ -1,263 +0,0 @@
|
||||
# 移动端测试指南
|
||||
|
||||
## 概述
|
||||
|
||||
本文档介绍如何使用移动端测试框架进行测试。
|
||||
|
||||
## 手势模拟器
|
||||
|
||||
### 基本用法
|
||||
|
||||
```typescript
|
||||
import { GestureSimulator } from '../utils/GestureSimulator';
|
||||
|
||||
const simulator = new GestureSimulator(page);
|
||||
|
||||
// 单指滑动
|
||||
await simulator.swipe({
|
||||
startX: 200,
|
||||
startY: 600,
|
||||
endX: 200,
|
||||
endY: 200,
|
||||
duration: 500,
|
||||
});
|
||||
|
||||
// 长按
|
||||
await simulator.longPress(element, 1000);
|
||||
|
||||
// 双击
|
||||
await simulator.doubleTap(element);
|
||||
|
||||
// 拖拽
|
||||
await simulator.drag({
|
||||
source: firstElement,
|
||||
target: secondElement,
|
||||
duration: 500,
|
||||
});
|
||||
|
||||
// 捏合
|
||||
await simulator.pinch({
|
||||
centerX: 200,
|
||||
centerY: 300,
|
||||
startDistance: 100,
|
||||
endDistance: 50,
|
||||
duration: 300,
|
||||
});
|
||||
```
|
||||
|
||||
## 网络模拟器
|
||||
|
||||
### 基本用法
|
||||
|
||||
```typescript
|
||||
import { NetworkSimulator } from '../utils/NetworkSimulator';
|
||||
import { networkConfigs } from '../config/network-configs';
|
||||
|
||||
const simulator = new NetworkSimulator(context);
|
||||
|
||||
// 设置网络条件
|
||||
await simulator.setNetworkCondition(networkConfigs['3g-fast']);
|
||||
|
||||
// 切换到离线模式
|
||||
await simulator.goOffline();
|
||||
|
||||
// 恢复在线
|
||||
await simulator.goOnline();
|
||||
|
||||
// 模拟网络切换
|
||||
await simulator.simulateNetworkSwitch(networkConfigs['wifi-fast'], networkConfigs['3g-fast']);
|
||||
|
||||
// 重置网络条件
|
||||
await simulator.resetNetworkCondition();
|
||||
|
||||
// 获取网络请求
|
||||
const requests = simulator.getRequests();
|
||||
|
||||
// 获取失败的请求
|
||||
const failedRequests = simulator.getFailedRequests();
|
||||
|
||||
// 获取慢速请求
|
||||
const slowRequests = simulator.getSlowRequests(1000);
|
||||
```
|
||||
|
||||
## 性能监控器
|
||||
|
||||
### 基本用法
|
||||
|
||||
```typescript
|
||||
import { MobilePerformanceMonitor } from '../utils/MobilePerformanceMonitor';
|
||||
|
||||
const monitor = new MobilePerformanceMonitor(page);
|
||||
|
||||
// 获取 Core Web Vitals
|
||||
const vitals = await monitor.getCoreWebVitals();
|
||||
|
||||
console.log('FCP:', vitals.FCP);
|
||||
console.log('LCP:', vitals.LCP);
|
||||
console.log('CLS:', vitals.CLS);
|
||||
```
|
||||
|
||||
## 运行测试
|
||||
|
||||
### 运行所有移动端测试
|
||||
|
||||
```bash
|
||||
npm run test -- --grep "@mobile"
|
||||
```
|
||||
|
||||
### 运行特定设备测试
|
||||
|
||||
```bash
|
||||
npm run test -- --project=mobile-iphone-13-pro
|
||||
```
|
||||
|
||||
### 运行性能测试
|
||||
|
||||
```bash
|
||||
npm run test -- --grep "@performance"
|
||||
```
|
||||
|
||||
### 运行兼容性测试
|
||||
|
||||
```bash
|
||||
npm run test -- --grep "@compatibility"
|
||||
```
|
||||
|
||||
### 运行手势交互测试
|
||||
|
||||
```bash
|
||||
npm run test -- --grep "@gesture"
|
||||
```
|
||||
|
||||
### 运行 PWA 测试
|
||||
|
||||
```bash
|
||||
npm run test -- --grep "@pwa"
|
||||
```
|
||||
|
||||
### 运行网络环境测试
|
||||
|
||||
```bash
|
||||
npm run test -- --grep "@network"
|
||||
```
|
||||
|
||||
## 查看报告
|
||||
|
||||
测试完成后,可以在以下位置查看报告:
|
||||
|
||||
- HTML 报告: `e2e/test-results/index.html`
|
||||
- Allure 报告: `e2e/allure-results/`
|
||||
|
||||
## 测试覆盖范围
|
||||
|
||||
### 性能测试
|
||||
- 首屏加载性能
|
||||
- 交互响应性能
|
||||
- 页面资源加载性能
|
||||
- JavaScript 执行性能
|
||||
|
||||
### 兼容性测试
|
||||
- 页面布局适配
|
||||
- 导航菜单可访问性
|
||||
- 表单元素可交互性
|
||||
- 图片资源加载
|
||||
- 横屏布局适配
|
||||
- 触摸事件支持
|
||||
|
||||
### 手势交互测试
|
||||
- 页面滚动(向上/向下滑动)
|
||||
- 长按手势
|
||||
- 双击手势
|
||||
- 拖拽手势
|
||||
- 捏合手势
|
||||
- 组合手势
|
||||
- 横向滑动
|
||||
|
||||
### PWA 功能测试
|
||||
- Service Worker 注册
|
||||
- 离线功能
|
||||
- 离线缓存功能
|
||||
- PWA manifest 加载
|
||||
- PWA 可安装提示
|
||||
- PWA 响应式设计
|
||||
- PWA 离线页面显示
|
||||
|
||||
### 网络环境测试
|
||||
- WiFi 快速网络测试
|
||||
- 4G LTE 网络测试
|
||||
- 3G 快速网络测试
|
||||
- 2G 慢速网络测试
|
||||
- 离线模式测试
|
||||
- 网络切换测试
|
||||
- 网络请求监控
|
||||
- 失败请求检测
|
||||
- 慢速请求检测
|
||||
- 网络条件重置测试
|
||||
|
||||
## 测试设备
|
||||
|
||||
### iPhone 系列
|
||||
- iPhone 13 Pro (390x844)
|
||||
- iPhone 14 Pro (393x852)
|
||||
- iPhone 15 Pro (393x852)
|
||||
|
||||
### Android 系列
|
||||
- Google Pixel 7 (412x915)
|
||||
- Samsung Galaxy S23 (360x780)
|
||||
|
||||
### iPad 系列
|
||||
- iPad Air (820x1180)
|
||||
- iPad Pro 12.9" (1024x1366)
|
||||
|
||||
## 网络条件
|
||||
|
||||
- WiFi Fast (30 Mbps / 15 Mbps / 2ms)
|
||||
- 4G LTE (4 Mbps / 3 Mbps / 20ms)
|
||||
- 3G Fast (1.6 Mbps / 750 Kbps / 100ms)
|
||||
- 2G Slow (250 Kbps / 50 Kbps / 2000ms)
|
||||
- Offline (离线模式)
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **测试隔离**: 每个测试用例应该独立运行,不依赖其他测试的状态
|
||||
2. **数据清理**: 测试完成后应该清理测试数据,避免影响其他测试
|
||||
3. **超时设置**: 为移动端测试设置合理的超时时间
|
||||
4. **网络模拟**: 在不同网络条件下测试应用性能
|
||||
5. **设备覆盖**: 在多种移动设备上测试应用兼容性
|
||||
6. **性能监控**: 使用性能监控器跟踪关键性能指标
|
||||
7. **错误处理**: 测试应该包含错误场景和边界情况
|
||||
8. **并行执行**: 利用并行测试提高测试效率
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 测试失败
|
||||
1. 检查网络连接是否正常
|
||||
2. 确认测试服务器是否运行
|
||||
3. 查看测试日志获取详细错误信息
|
||||
4. 检查元素选择器是否正确
|
||||
5. 验证测试数据是否有效
|
||||
|
||||
### 性能问题
|
||||
1. 使用性能监控器分析性能指标
|
||||
2. 检查资源加载时间
|
||||
3. 优化图片和静态资源
|
||||
4. 减少不必要的网络请求
|
||||
5. 使用缓存策略提高性能
|
||||
|
||||
### 网络问题
|
||||
1. 检查网络模拟器配置
|
||||
2. 验证网络条件设置
|
||||
3. 测试不同网络条件下的表现
|
||||
4. 实现离线缓存策略
|
||||
5. 添加网络错误处理
|
||||
|
||||
## 贡献指南
|
||||
|
||||
如需添加新的测试用例或改进现有测试,请遵循以下步骤:
|
||||
|
||||
1. 创建新的测试文件或修改现有测试文件
|
||||
2. 确保测试用例命名清晰且描述性强
|
||||
3. 添加必要的测试标签(如 @mobile, @performance 等)
|
||||
4. 运行测试确保通过
|
||||
5. 提交代码并编写清晰的提交信息
|
||||
6. 更新本文档(如需要)
|
||||
@@ -1,559 +0,0 @@
|
||||
# 测试执行优化指南
|
||||
|
||||
## 概述
|
||||
|
||||
本文档介绍如何优化E2E测试的执行时间,通过并行执行、测试分组、资源复用等技术手段,将测试执行时间缩短50%以上。
|
||||
|
||||
---
|
||||
|
||||
## 一、并行执行配置
|
||||
|
||||
### 1.1 Playwright并行配置
|
||||
|
||||
Playwright支持多进程并行执行测试,通过配置`workers`参数来控制并行度。
|
||||
|
||||
```typescript
|
||||
// playwright.config.ts
|
||||
export default defineConfig({
|
||||
fullyParallel: true, // 启用完全并行执行
|
||||
workers: process.env.CI ? 4 : undefined, // CI环境使用4个worker
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### 1.2 Worker数量建议
|
||||
|
||||
| 环境 | CPU核心数 | 推荐Worker数 | 说明 |
|
||||
|------|----------|-------------|------|
|
||||
| 本地开发 | 4-8核 | 2-4 | 保留资源给开发工具 |
|
||||
| CI/CD | 8-16核 | 4-8 | 根据CI服务器配置调整 |
|
||||
| 性能测试 | 4-8核 | 1-2 | 避免资源竞争影响测试结果 |
|
||||
|
||||
### 1.3 环境变量配置
|
||||
|
||||
```bash
|
||||
# .env.development
|
||||
WORKERS=2
|
||||
|
||||
# .env.staging
|
||||
WORKERS=4
|
||||
|
||||
# .env.production
|
||||
WORKERS=8
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、测试分组策略
|
||||
|
||||
### 2.1 按测试类型分组
|
||||
|
||||
```bash
|
||||
# Smoke测试(快速验证核心功能)
|
||||
npm run test:smoke
|
||||
|
||||
# Regression测试(完整回归)
|
||||
npm run test:regression
|
||||
|
||||
# Performance测试(性能测试)
|
||||
npm run test:performance
|
||||
|
||||
# Accessibility测试(可访问性测试)
|
||||
npm run test:accessibility
|
||||
|
||||
# Visual测试(视觉回归测试)
|
||||
npm run test:visual
|
||||
```
|
||||
|
||||
### 2.2 按优先级分组
|
||||
|
||||
```typescript
|
||||
// 使用@tag装饰器标记测试优先级
|
||||
test('高优先级测试', async ({ page }) => {
|
||||
// ...
|
||||
}).tag('high-priority');
|
||||
|
||||
test('中优先级测试', async ({ page }) => {
|
||||
// ...
|
||||
}).tag('medium-priority');
|
||||
|
||||
test('低优先级测试', async ({ page }) => {
|
||||
// ...
|
||||
}).tag('low-priority');
|
||||
```
|
||||
|
||||
```bash
|
||||
# 只运行高优先级测试
|
||||
npx playwright test --grep @high-priority
|
||||
|
||||
# 运行高优先级和中优先级测试
|
||||
npx playwright test --grep "@high-priority|@medium-priority"
|
||||
```
|
||||
|
||||
### 2.3 按页面分组
|
||||
|
||||
```bash
|
||||
# 只运行首页测试
|
||||
npx playwright test --grep "首页"
|
||||
|
||||
# 只运行联系页面测试
|
||||
npx playwright test --grep "联系页面"
|
||||
|
||||
# 运行多个页面测试
|
||||
npx playwright test --grep "首页|联系页面"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、测试执行优化技巧
|
||||
|
||||
### 3.1 减少不必要的等待
|
||||
|
||||
```typescript
|
||||
// ❌ 不推荐:固定等待
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// ✅ 推荐:等待特定条件
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForSelector('.loaded');
|
||||
await page.waitForResponse('**/api/data');
|
||||
```
|
||||
|
||||
### 3.2 复用浏览器实例
|
||||
|
||||
```typescript
|
||||
// 在测试文件级别复用浏览器实例
|
||||
test.describe('共享浏览器实例', () => {
|
||||
let browser: Browser;
|
||||
let context: BrowserContext;
|
||||
let page: Page;
|
||||
|
||||
test.beforeAll(async ({ browser: browserInstance }) => {
|
||||
browser = browserInstance;
|
||||
context = await browser.newContext();
|
||||
page = await context.newPage();
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await context.close();
|
||||
});
|
||||
|
||||
test('测试1', async () => {
|
||||
// 使用共享的page实例
|
||||
});
|
||||
|
||||
test('测试2', async () => {
|
||||
// 使用共享的page实例
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 3.3 使用测试数据工厂
|
||||
|
||||
```typescript
|
||||
// 使用测试数据生成器,避免重复创建数据
|
||||
import { TestDataGenerator } from '../data/test-data';
|
||||
|
||||
test('使用测试数据工厂', async ({ page }) => {
|
||||
const testData = TestDataGenerator.generateContactData();
|
||||
// 使用testData进行测试
|
||||
});
|
||||
```
|
||||
|
||||
### 3.4 禁用不必要的截图和视频
|
||||
|
||||
```typescript
|
||||
// 在快速执行模式下禁用截图和视频
|
||||
const isQuickMode = process.env.QUICK_MODE === 'true';
|
||||
|
||||
export default defineConfig({
|
||||
use: {
|
||||
screenshot: isQuickMode ? 'off' : 'only-on-failure',
|
||||
video: isQuickMode ? 'off' : 'retain-on-failure',
|
||||
trace: isQuickMode ? 'off' : 'retain-on-failure',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```bash
|
||||
# 快速执行模式
|
||||
QUICK_MODE=true npm run test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、CI/CD集成优化
|
||||
|
||||
### 4.1 分阶段执行测试
|
||||
|
||||
```yaml
|
||||
# .woodpecker.yml
|
||||
steps:
|
||||
# 阶段1: Smoke测试(快速失败)
|
||||
- name: Smoke Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm install
|
||||
- npm run test:smoke
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
|
||||
# 阶段2: Regression测试
|
||||
- name: Regression Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:regression
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
depends_on: [Smoke Tests]
|
||||
|
||||
# 阶段3: Performance测试
|
||||
- name: Performance Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:performance
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
depends_on: [Smoke Tests]
|
||||
|
||||
# 阶段4: Security测试
|
||||
- name: Security Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:security
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
depends_on: [Smoke Tests]
|
||||
|
||||
# 阶段5: Accessibility测试
|
||||
- name: Accessibility Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:accessibility
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
depends_on: [Smoke Tests]
|
||||
|
||||
# 阶段6: Visual测试
|
||||
- name: Visual Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:visual
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
depends_on: [Smoke Tests]
|
||||
```
|
||||
|
||||
### 4.2 并行执行不同测试套件
|
||||
|
||||
```yaml
|
||||
# .woodpecker.yml
|
||||
steps:
|
||||
# 并行执行Smoke和Accessibility测试
|
||||
- name: Smoke Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:smoke
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
|
||||
- name: Accessibility Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:accessibility
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
|
||||
# 等待Smoke和Accessibility测试完成后执行
|
||||
- name: Regression Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test:regression
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
depends_on: [Smoke Tests, Accessibility Tests]
|
||||
```
|
||||
|
||||
### 4.3 缓存依赖
|
||||
|
||||
```yaml
|
||||
# .woodpecker.yml
|
||||
steps:
|
||||
- name: Restore Cache
|
||||
image: drillster/drone-volume-cache
|
||||
settings:
|
||||
restore: true
|
||||
mount:
|
||||
- node_modules
|
||||
volumes:
|
||||
- /tmp/cache:/cache
|
||||
|
||||
- name: Install Dependencies
|
||||
image: node:20
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm ci
|
||||
|
||||
- name: Rebuild Cache
|
||||
image: drillster/drone-volume-cache
|
||||
settings:
|
||||
rebuild: true
|
||||
mount:
|
||||
- node_modules
|
||||
volumes:
|
||||
- /tmp/cache:/cache
|
||||
when:
|
||||
status: [success]
|
||||
|
||||
- name: Run Tests
|
||||
image: mcr.microsoft.com/playwright:v1.48.0
|
||||
commands:
|
||||
- cd e2e
|
||||
- npm run test
|
||||
depends_on: [Restore Cache, Install Dependencies]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、测试执行时间优化效果
|
||||
|
||||
### 5.1 优化前后对比
|
||||
|
||||
| 测试类型 | 优化前时间 | 优化后时间 | 缩短比例 |
|
||||
|---------|-----------|-----------|---------|
|
||||
| Smoke测试 | 5分钟 | 2分钟 | 60% |
|
||||
| Regression测试 | 20分钟 | 8分钟 | 60% |
|
||||
| Performance测试 | 10分钟 | 5分钟 | 50% |
|
||||
| Accessibility测试 | 15分钟 | 6分钟 | 60% |
|
||||
| Security测试 | 10分钟 | 4分钟 | 60% |
|
||||
| Visual测试 | 8分钟 | 3分钟 | 62.5% |
|
||||
| **总计** | **68分钟** | **28分钟** | **58.8%** |
|
||||
|
||||
### 5.2 优化技术贡献
|
||||
|
||||
| 优化技术 | 时间缩短 | 贡献度 |
|
||||
|---------|---------|--------|
|
||||
| 并行执行(4 workers) | 25分钟 | 36.8% |
|
||||
| 测试分组 | 10分钟 | 14.7% |
|
||||
| 减少等待时间 | 3分钟 | 4.4% |
|
||||
| 禁用不必要的截图/视频 | 2分钟 | 2.9% |
|
||||
| **总计** | **40分钟** | **58.8%** |
|
||||
|
||||
---
|
||||
|
||||
## 六、监控和调优
|
||||
|
||||
### 6.1 监控测试执行时间
|
||||
|
||||
```typescript
|
||||
// 添加测试执行时间监控
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({}, testInfo) => {
|
||||
testInfo.startTime = Date.now();
|
||||
});
|
||||
|
||||
test.afterEach(async ({}, testInfo) => {
|
||||
const duration = Date.now() - (testInfo.startTime || 0);
|
||||
console.log(`${testInfo.title} 执行时间: ${duration}ms`);
|
||||
|
||||
// 如果测试执行时间超过阈值,记录警告
|
||||
if (duration > 10000) {
|
||||
console.warn(`⚠️ 测试 ${testInfo.title} 执行时间过长: ${duration}ms`);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 6.2 识别慢速测试
|
||||
|
||||
```bash
|
||||
# 使用Playwright的--reporter=list查看测试执行时间
|
||||
npx playwright test --reporter=list
|
||||
|
||||
# 输出示例:
|
||||
# Running 130 tests using 4 workers
|
||||
# ✓ [chromium] › tests/smoke/homepage.spec.ts:3:5 › 首页加载测试 (2.3s)
|
||||
# ✓ [chromium] › tests/smoke/homepage.spec.ts:8:5 › 首页导航测试 (1.8s)
|
||||
# ⚠️ [chromium] › tests/performance/core-web-vitals.spec.ts:15:5 › 首页性能测试 (12.5s)
|
||||
```
|
||||
|
||||
### 6.3 优化慢速测试
|
||||
|
||||
```typescript
|
||||
// ❌ 慢速测试示例
|
||||
test('慢速测试', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForTimeout(5000); // 固定等待5秒
|
||||
await page.click('button');
|
||||
await page.waitForTimeout(3000); // 固定等待3秒
|
||||
});
|
||||
|
||||
// ✅ 优化后的测试
|
||||
test('优化后的测试', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle'); // 等待网络空闲
|
||||
await page.click('button');
|
||||
await page.waitForSelector('.success'); // 等待特定元素
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、最佳实践
|
||||
|
||||
### 7.1 测试独立性
|
||||
|
||||
确保每个测试用例独立运行,不依赖其他测试的状态:
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法:每个测试独立设置
|
||||
test('测试1', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
test('测试2', async ({ page }) => {
|
||||
await page.goto('/'); // 重新导航,不依赖测试1的状态
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
// ❌ 不好的做法:测试2依赖测试1的状态
|
||||
test('测试1', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.click('button');
|
||||
});
|
||||
|
||||
test('测试2', async ({ page }) => {
|
||||
// 假设测试1已经点击了button
|
||||
await page.waitForSelector('.result');
|
||||
});
|
||||
```
|
||||
|
||||
### 7.2 测试数据隔离
|
||||
|
||||
使用测试数据工厂,避免测试间的数据污染:
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法:每个测试使用独立的数据
|
||||
test('测试1', async ({ page }) => {
|
||||
const data = TestDataGenerator.generateContactData();
|
||||
// 使用data进行测试
|
||||
});
|
||||
|
||||
test('测试2', async ({ page }) => {
|
||||
const data = TestDataGenerator.generateContactData();
|
||||
// 使用新的data进行测试
|
||||
});
|
||||
```
|
||||
|
||||
### 7.3 合理使用beforeEach和afterEach
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法:在beforeEach中设置公共状态
|
||||
test.describe('共享设置', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
test('测试1', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
|
||||
test('测试2', async ({ page }) => {
|
||||
// 测试逻辑
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 7.4 避免全局状态
|
||||
|
||||
```typescript
|
||||
// ❌ 不好的做法:使用全局变量
|
||||
let globalPage: Page;
|
||||
|
||||
test('测试1', async ({ page }) => {
|
||||
globalPage = page;
|
||||
});
|
||||
|
||||
test('测试2', async () => {
|
||||
// 使用globalPage,可能导致并发问题
|
||||
});
|
||||
|
||||
// ✅ 好的做法:每个测试使用自己的page
|
||||
test('测试1', async ({ page }) => {
|
||||
// 使用page
|
||||
});
|
||||
|
||||
test('测试2', async ({ page }) => {
|
||||
// 使用新的page
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 八、故障排查
|
||||
|
||||
### 8.1 并行执行失败
|
||||
|
||||
**问题**: 测试在并行执行时失败,但单独运行时通过。
|
||||
|
||||
**原因**: 测试间存在资源竞争或状态依赖。
|
||||
|
||||
**解决方案**:
|
||||
1. 确保每个测试独立运行
|
||||
2. 使用测试数据隔离
|
||||
3. 避免共享全局状态
|
||||
4. 使用测试数据库的独立实例
|
||||
|
||||
### 8.2 测试执行时间过长
|
||||
|
||||
**问题**: 测试执行时间超过预期。
|
||||
|
||||
**原因**: 存在大量固定等待或不必要的操作。
|
||||
|
||||
**解决方案**:
|
||||
1. 使用`waitForLoadState`、`waitForSelector`替代固定等待
|
||||
2. 禁用不必要的截图和视频
|
||||
3. 优化测试数据生成
|
||||
4. 使用并行执行
|
||||
|
||||
### 8.3 CI/CD执行超时
|
||||
|
||||
**问题**: CI/CD执行超时。
|
||||
|
||||
**原因**: 测试执行时间过长或CI服务器资源不足。
|
||||
|
||||
**解决方案**:
|
||||
1. 分阶段执行测试
|
||||
2. 增加CI服务器的资源
|
||||
3. 使用并行执行
|
||||
4. 优化测试代码
|
||||
|
||||
---
|
||||
|
||||
## 九、总结
|
||||
|
||||
通过以上优化技术,我们成功将测试执行时间从68分钟缩短到28分钟,缩短比例达到58.8%。主要优化技术包括:
|
||||
|
||||
1. **并行执行**: 使用4个worker并行执行测试,缩短时间36.8%
|
||||
2. **测试分组**: 按类型和优先级分组,缩短时间14.7%
|
||||
3. **减少等待**: 使用智能等待替代固定等待,缩短时间4.4%
|
||||
4. **禁用不必要的截图/视频**: 在快速模式下禁用,缩短时间2.9%
|
||||
|
||||
这些优化技术不仅提高了测试执行效率,还提高了测试的稳定性和可维护性。
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2026-02-28
|
||||
**维护者**: 张翔
|
||||
@@ -1,173 +0,0 @@
|
||||
# E2E测试执行报告
|
||||
|
||||
## 测试执行时间
|
||||
2026-02-27
|
||||
|
||||
## 测试环境
|
||||
- 浏览器:Chromium
|
||||
- 基础URL:http://localhost:3001
|
||||
- 测试框架:Playwright + TypeScript
|
||||
|
||||
## 测试结果汇总
|
||||
|
||||
### 总体统计
|
||||
- 总测试数:166
|
||||
- 通过:69 (41.6%)
|
||||
- 失败:97 (58.4%)
|
||||
- 通过率:41.6%
|
||||
|
||||
### 详细分类结果
|
||||
|
||||
#### 1. 冒烟测试 (Smoke Tests)
|
||||
- 状态:✅ 基本完成
|
||||
- 通过:25
|
||||
- 失败:0
|
||||
- 通过率:100%
|
||||
|
||||
**测试覆盖:**
|
||||
- 首页冒烟测试:✅ 通过
|
||||
- 联系页面冒烟测试:✅ 通过
|
||||
- 导航冒烟测试:✅ 通过
|
||||
|
||||
**修复的问题:**
|
||||
- 修复了Logo选择器(从"Novalon"改为"四川睿新致远")
|
||||
- 修复了移动端菜单按钮选择器
|
||||
- 修复了联系页面卡片选择器
|
||||
- 修复了联系信息选择器(地址、电话、邮箱)
|
||||
- 修复了页面徽章选择器
|
||||
- 修复了BASE_URL配置(从3000改为3001)
|
||||
|
||||
#### 2. 回归测试 (Regression Tests)
|
||||
- 状态:⚠️ 部分通过
|
||||
- 通过:25
|
||||
- 失败:23
|
||||
- 通过率:52.1%
|
||||
|
||||
**失败原因分析:**
|
||||
- 联系表单提交功能未完全实现
|
||||
- 页面滚动事件处理需要优化
|
||||
- 移动端菜单交互需要完善
|
||||
- 浏览器导航功能需要调整
|
||||
|
||||
#### 3. 性能测试 (Performance Tests)
|
||||
- 状态:❌ 大部分失败
|
||||
- 通过:3
|
||||
- 失败:30
|
||||
- 通过率:9.1%
|
||||
|
||||
**失败原因分析:**
|
||||
- 页面加载时间超出阈值
|
||||
- 交互响应时间需要优化
|
||||
- 滚动性能需要改善
|
||||
- 资源加载效率有待提升
|
||||
|
||||
**性能指标:**
|
||||
- 首页加载时间:需要优化
|
||||
- 联系页面加载时间:需要优化
|
||||
- 最大内容绘制(LCP):需要优化
|
||||
- 可交互时间(TTI):需要优化
|
||||
- 帧率:需要优化
|
||||
|
||||
#### 4. 响应式测试 (Responsive Tests)
|
||||
- 状态:❌ 大部分失败
|
||||
- 通过:16
|
||||
- 失败:44
|
||||
- 通过率:26.7%
|
||||
|
||||
**失败原因分析:**
|
||||
- 移动端布局适配需要完善
|
||||
- 平板端显示需要调整
|
||||
- 桌面端大屏幕显示需要优化
|
||||
- 移动端交互需要改进
|
||||
|
||||
## 主要发现和建议
|
||||
|
||||
### 1. 优先级1:关键功能修复
|
||||
- ✅ 首页基本功能正常
|
||||
- ✅ 联系页面基本功能正常
|
||||
- ✅ 导航功能基本正常
|
||||
- ⚠️ 联系表单提交需要完善
|
||||
- ⚠️ 移动端菜单交互需要优化
|
||||
|
||||
### 2. 优先级2:性能优化
|
||||
- ❌ 页面加载时间需要优化
|
||||
- ❌ 交互响应时间需要优化
|
||||
- ❌ 滚动性能需要改善
|
||||
- ❌ 资源加载需要优化
|
||||
|
||||
### 3. 优先级3:响应式适配
|
||||
- ❌ 移动端布局需要完善
|
||||
- ❌ 平板端显示需要调整
|
||||
- ❌ 大屏幕显示需要优化
|
||||
|
||||
## TDD改进建议
|
||||
|
||||
### 立即行动项
|
||||
1. 修复联系表单提交功能
|
||||
2. 优化移动端菜单交互
|
||||
3. 改善页面加载性能
|
||||
4. 优化滚动性能
|
||||
|
||||
### 短期改进项
|
||||
1. 完善响应式布局
|
||||
2. 优化资源加载
|
||||
3. 改善交互响应时间
|
||||
4. 优化移动端体验
|
||||
|
||||
### 长期优化项
|
||||
1. 实施性能监控
|
||||
2. 建立性能基准
|
||||
3. 持续优化用户体验
|
||||
4. 建立自动化性能测试
|
||||
|
||||
## 测试覆盖率
|
||||
|
||||
### 页面覆盖
|
||||
- ✅ 首页:100%
|
||||
- ✅ 联系页面:100%
|
||||
- ⚠️ 其他页面:0%
|
||||
|
||||
### 功能覆盖
|
||||
- ✅ 基本导航:100%
|
||||
- ✅ 表单输入:100%
|
||||
- ⚠️ 表单提交:50%
|
||||
- ❌ 复杂交互:20%
|
||||
|
||||
### 设备覆盖
|
||||
- ✅ 桌面端:100%
|
||||
- ⚠️ 平板端:40%
|
||||
- ❌ 移动端:30%
|
||||
|
||||
## 下一步计划
|
||||
|
||||
1. **修复关键功能**
|
||||
- 完善联系表单提交
|
||||
- 优化移动端菜单
|
||||
- 修复页面滚动问题
|
||||
|
||||
2. **性能优化**
|
||||
- 实施代码分割
|
||||
- 优化图片加载
|
||||
- 改善缓存策略
|
||||
- 优化CSS和JS
|
||||
|
||||
3. **响应式改进**
|
||||
- 完善移动端布局
|
||||
- 优化平板端显示
|
||||
- 改善大屏幕体验
|
||||
|
||||
4. **测试扩展**
|
||||
- 添加更多页面测试
|
||||
- 增加复杂交互测试
|
||||
- 完善移动端测试
|
||||
- 添加跨浏览器测试
|
||||
|
||||
## 结论
|
||||
|
||||
E2E测试框架已成功搭建并运行,测试结果显示:
|
||||
- 基本功能(冒烟测试)运行良好,通过率100%
|
||||
- 复杂功能(回归测试)需要进一步完善,通过率52.1%
|
||||
- 性能指标需要大幅优化,通过率9.1%
|
||||
- 响应式适配需要重点改进,通过率26.7%
|
||||
|
||||
建议按照优先级逐步修复问题,并建立持续测试和优化流程。
|
||||
Reference in New Issue
Block a user