Files
张翔 0175799004 docs: 删除过时的文档和测试报告文件
删除不再需要的文档、测试报告和计划文件,包括标题层级规范、颜色优化报告、测试框架文档等
2026-03-07 15:37:19 +08:00

606 lines
13 KiB
Markdown

# 测试文档
## 测试概述
项目使用 Playwright 进行端到端(E2E)测试,测试框架位于 `e2e/` 目录,采用 Page Object 模式组织测试代码。
## 测试框架结构
```
e2e/
├── src/
│ ├── config/ # 配置文件
│ │ ├── environments.ts # 环境配置
│ │ └── network-configs.ts # 网络配置
│ ├── data/ # 测试数据
│ │ └── test-data.ts
│ ├── fixtures/ # 测试 Fixtures
│ │ ├── base.fixture.ts # 基础 Fixture
│ │ └── a11y.fixture.ts # 可访问性 Fixture
│ ├── pages/ # Page Object Model
│ │ ├── BasePage.ts # 基础页面
│ │ ├── HomePage.ts # 首页
│ │ ├── AboutPage.ts # 关于页
│ │ ├── CasesPage.ts # 案例页
│ │ ├── ContactPage.ts # 联系页
│ │ ├── NewsPage.ts # 新闻页
│ │ ├── ProductsPage.ts # 产品页
│ │ ├── ServicesPage.ts # 服务页
│ │ └── SolutionsPage.ts # 解决方案页
│ └── tests/ # 测试用例
│ ├── accessibility/ # 可访问性测试
│ ├── debug/ # 调试测试
│ ├── deployment/ # 部署就绪测试
│ ├── error-handling/ # 错误处理测试
│ ├── mobile/ # 移动端测试
│ ├── performance/ # 性能测试
│ ├── regression/ # 回归测试
│ ├── responsive/ # 响应式测试
│ ├── security/ # 安全测试
│ ├── smoke/ # 冒烟测试
│ ├── utils/ # 工具测试
│ └── visual/ # 视觉回归测试
├── playwright.config.ts # Playwright 配置
├── package.json
└── .env.example
```
## 测试类型
### 1. 冒烟测试 (Smoke Tests)
**目录**: `e2e/src/tests/smoke/`
**目的**: 验证核心功能是否正常工作
**测试文件**:
- `all-pages.spec.ts` - 所有页面加载测试
- `home-page.smoke.spec.ts` - 首页冒烟测试
- `contact-page.smoke.spec.ts` - 联系页冒烟测试
- `navigation.smoke.spec.ts` - 导航冒烟测试
**运行命令**:
```bash
npm run test:smoke
# 或
npx playwright test --grep @smoke
```
### 2. 回归测试 (Regression Tests)
**目录**: `e2e/src/tests/regression/`
**目的**: 确保新代码没有破坏现有功能
**测试文件**:
- `contact-form.regression.spec.ts` - 联系表单回归测试
- `home-page.regression.spec.ts` - 首页回归测试
- `navigation.spec.ts` - 导航回归测试
**运行命令**:
```bash
npm run test:regression
# 或
npx playwright test --grep @regression
```
### 3. 性能测试 (Performance Tests)
**目录**: `e2e/src/tests/performance/`
**目的**: 验证页面性能指标
**测试文件**:
- `core-web-vitals.spec.ts` - Core Web Vitals 测试
- `performance.spec.ts` - 通用性能测试
- `image-loading.spec.ts` - 图片加载性能
- `interaction-performance.spec.ts` - 交互性能测试
**监控指标**:
- LCP (Largest Contentful Paint) < 2.5s
- FID (First Input Delay) < 100ms
- CLS (Cumulative Layout Shift) < 0.1
- TTFB (Time to First Byte) < 600ms
**运行命令**:
```bash
npm run test:performance
# 或
npx playwright test --grep @performance
```
### 4. 响应式测试 (Responsive Tests)
**目录**: `e2e/src/tests/responsive/`
**目的**: 验证多设备适配
**测试文件**:
- `responsive.spec.ts` - 响应式布局测试
- `mobile-interaction.spec.ts` - 移动端交互测试
**测试设备**:
- Desktop: 1920x1080, 1366x768
- Tablet: iPad Pro (1024x1366), iPad Air (820x1180)
- Mobile: iPhone 12 (390x844), iPhone SE (375x667), Pixel 5 (393x851)
**运行命令**:
```bash
npm run test:responsive
# 或
npx playwright test --grep @responsive
```
### 5. 可访问性测试 (Accessibility Tests)
**目录**: `e2e/src/tests/accessibility/`
**目的**: 验证 WCAG 合规性
**测试文件**:
- `accessibility.spec.ts` - 可访问性测试
- `wcag-compliance.spec.ts` - WCAG 合规测试
**检查项**:
- 颜色对比度 ≥ 4.5:1 (AA 级别)
- 键盘导航支持
- 屏幕阅读器兼容
- ARIA 属性正确性
- 焦点顺序合理
**运行命令**:
```bash
npm run test:accessibility
# 或
npx playwright test --grep @accessibility
```
### 6. 安全测试 (Security Tests)
**目录**: `e2e/src/tests/security/`
**目的**: 验证安全防护措施
**测试文件**:
- `security.spec.ts` - 通用安全测试
- `xss-protection.spec.ts` - XSS 防护测试
- `csrf-protection.spec.ts` - CSRF 防护测试
**检查项**:
- XSS 攻击防护
- CSRF Token 验证
- 安全头部配置
- 表单验证
**运行命令**:
```bash
npm run test:security
# 或
npx playwright test --grep @security
```
### 7. 视觉回归测试 (Visual Tests)
**目录**: `e2e/src/tests/visual/`
**目的**: 检测 UI 变化
**测试文件**:
- `home-page.visual.spec.ts` - 首页视觉测试
- `contact-page.visual.spec.ts` - 联系页视觉测试
- `visual-regression.spec.ts` - 视觉回归测试
**快照目录**:
- `*-snapshots/` - 基线快照
**运行命令**:
```bash
npm run test:visual
# 或
npx playwright test --grep @visual
```
**更新快照**:
```bash
npx playwright test --grep @visual --update-snapshots
```
### 8. 移动端测试 (Mobile Tests)
**目录**: `e2e/src/tests/mobile/`
**目的**: 验证移动端功能
**测试文件**:
- `compatibility/mobile-compatibility.spec.ts` - 兼容性测试
- `gesture/mobile-gesture.spec.ts` - 手势测试
- `network/network-environment.spec.ts` - 网络环境测试
- `performance/mobile-performance.spec.ts` - 移动性能测试
- `pwa/pwa-functionality.spec.ts` - PWA 功能测试
- `mobile-ux.spec.ts` - 移动端 UX 测试
### 9. 部署就绪测试 (Deployment Tests)
**目录**: `e2e/src/tests/deployment/`
**目的**: 验证部署前检查
**测试文件**:
- `deployment-readiness.spec.ts` - 部署就绪检查
- `quick-check.spec.ts` - 快速检查
## Page Object Model
### 基础页面类
```typescript
// e2e/src/pages/BasePage.ts
export class BasePage {
readonly page: Page;
constructor(page: Page) {
this.page = page;
}
async navigate(path: string) {
await this.page.goto(path);
}
async waitForPageLoad() {
await this.page.waitForLoadState('networkidle');
}
async takeScreenshot(name: string) {
await this.page.screenshot({ path: `screenshots/${name}.png` });
}
}
```
### 首页 Page Object
```typescript
// e2e/src/pages/HomePage.ts
import { BasePage } from './BasePage';
export class HomePage extends BasePage {
readonly heroSection: Locator;
readonly servicesSection: Locator;
readonly productsSection: Locator;
constructor(page: Page) {
super(page);
this.heroSection = page.locator('[data-testid="hero-section"]');
this.servicesSection = page.locator('#services');
this.productsSection = page.locator('#products');
}
async goto() {
await this.navigate('/');
await this.waitForPageLoad();
}
async scrollToSection(sectionId: string) {
await this.page.locator(`#${sectionId}`).scrollIntoViewIfNeeded();
}
}
```
### 使用示例
```typescript
// e2e/src/tests/smoke/home-page.smoke.spec.ts
import { test, expect } from '@playwright/test';
import { HomePage } from '../../pages/HomePage';
test.describe('首页冒烟测试', () => {
let homePage: HomePage;
test.beforeEach(async ({ page }) => {
homePage = new HomePage(page);
await homePage.goto();
});
test('首页加载成功', async () => {
await expect(homePage.heroSection).toBeVisible();
});
});
```
## 测试配置
### Playwright 配置
```typescript
// e2e/playwright.config.ts
export default defineConfig({
testDir: './src/tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 4 : '50%',
reporter: [
['html'],
['json', { outputFile: 'test-results/results.json' }],
['junit', { outputFile: 'test-results/junit.xml' }],
['allure-playwright'],
],
timeout: 90000,
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'on-first-retry',
headless: true,
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
{ name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } },
{ name: 'Mobile Safari', use: { ...devices['iPhone 12'] } },
],
webServer: {
command: 'cd .. && npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});
```
### 环境配置
```typescript
// e2e/src/config/environments.ts
export interface Environment {
name: string;
baseURL: string;
retries: number;
trace: 'on' | 'off' | 'on-first-retry';
screenshot: 'on' | 'off' | 'only-on-failure';
video: 'on' | 'off' | 'on-first-retry';
headless: boolean;
slowMo: number;
}
export const environments: Record<string, Environment> = {
development: {
name: 'development',
baseURL: 'http://localhost:3000',
retries: 0,
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'on-first-retry',
headless: true,
slowMo: 0,
},
production: {
name: 'production',
baseURL: 'https://www.novalon.cn',
retries: 2,
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'on-first-retry',
headless: true,
slowMo: 0,
},
};
export function getEnvironment(): Environment {
const env = process.env.TEST_ENV || 'development';
return environments[env];
}
```
## 运行测试
### 本地运行
```bash
# 进入测试目录
cd e2e
# 安装依赖
npm install
# 安装浏览器
npx playwright install
# 运行所有测试
npm run test
# 运行特定测试
npx playwright test path/to/test.spec.ts
# 运行带标签的测试
npx playwright test --grep @smoke
# UI 模式
npm run test:ui
# 调试模式
npm run test:debug
# 有头模式
npm run test:headed
```
### CI 环境运行
```bash
# CI 模式(禁止 only、增加重试)
CI=true npx playwright test
```
## 测试报告
### HTML 报告
```bash
npx playwright show-report
```
### Allure 报告
```bash
# 生成报告
npm run test:allure
# 打开报告
npm run test:allure:open
# 实时服务
npm run test:allure:serve
```
### JUnit 报告
用于 CI 集成,输出到 `test-results/junit.xml`
## 测试最佳实践
### 1. 使用数据测试 ID
```tsx
// 组件中
<div data-testid="hero-section">
// 测试中
await page.locator('[data-testid="hero-section"]')
```
### 2. 等待策略
```typescript
// 等待元素可见
await expect(locator).toBeVisible();
// 等待网络空闲
await page.waitForLoadState('networkidle');
// 等待特定响应
await page.waitForResponse('**/api/contact');
```
### 3. 避免硬编码等待
```typescript
// 不推荐
await page.waitForTimeout(1000);
// 推荐
await expect(locator).toBeVisible();
```
### 4. 使用 Fixtures
```typescript
// e2e/src/fixtures/base.fixture.ts
import { test as base } from '@playwright/test';
import { HomePage } from '../pages/HomePage';
export const test = base.extend<{
homePage: HomePage;
}>({
homePage: async ({ page }, use) => {
const homePage = new HomePage(page);
await use(homePage);
},
});
```
### 5. 测试隔离
```typescript
test.describe('测试组', () => {
test.beforeEach(async ({ page }) => {
// 每个测试前的初始化
});
test.afterEach(async ({ page }) => {
// 每个测试后的清理
});
});
```
## CI 集成
### Woodpecker CI 配置
```yaml
# .woodpecker.yml
pipeline:
e2e-tests:
image: node:18-alpine
environment:
NODE_ENV: test
CI: true
commands:
- cd e2e
- npm ci
- npx playwright install --with-deps chromium
- npm run test:ci
when:
event:
- push
- pull_request
```
### 测试命令
```json
{
"scripts": {
"test": "playwright test",
"test:smoke": "playwright test --grep @smoke",
"test:regression": "playwright test --grep @regression",
"test:performance": "playwright test --grep @performance",
"test:responsive": "playwright test --grep @responsive",
"test:visual": "playwright test --grep @visual",
"test:accessibility": "playwright test --grep @accessibility",
"test:security": "playwright test --grep @security",
"test:ci": "playwright test --reporter=html,json,junit"
}
}
```
## 调试技巧
### 1. Trace Viewer
```bash
# 运行测试并生成 trace
npx playwright test --trace on
# 查看 trace
npx playwright show-trace trace.zip
```
### 2. 截图和视频
```typescript
// 手动截图
await page.screenshot({ path: 'debug.png' });
// 元素截图
await locator.screenshot({ path: 'element.png' });
// 全页截图
await page.screenshot({ path: 'full.png', fullPage: true });
```
### 3. 控制台日志
```typescript
// 监听控制台
page.on('console', msg => console.log(msg.text()));
// 监听页面错误
page.on('pageerror', error => console.error(error));
```
### 4. Playwright Inspector
```bash
npx playwright test --debug
```